sl@0: // Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). sl@0: // All rights reserved. sl@0: // This component and the accompanying materials are made available sl@0: // under the terms of "Eclipse Public License v1.0" sl@0: // which accompanies this distribution, and is available sl@0: // at the URL "http://www.eclipse.org/legal/epl-v10.html". sl@0: // sl@0: // Initial Contributors: sl@0: // Nokia Corporation - initial contribution. sl@0: // sl@0: // Contributors: sl@0: // sl@0: // Description: sl@0: // sl@0: sl@0: #include "swdirectgdiengine.h" sl@0: #include sl@0: #include sl@0: sl@0: /** sl@0: @see MDirectGdiEngine::SetFont() sl@0: */ sl@0: void CSwDirectGdiEngine::SetFont(TUint32 /*aFontId*/) sl@0: { sl@0: // Do nothing. sl@0: // The SW adapter doesn't need the font ID to index a separate font cache because it uses the standard one. sl@0: } sl@0: sl@0: sl@0: /** sl@0: @see MDirectGdiEngine::ResetFont() sl@0: */ sl@0: void CSwDirectGdiEngine::ResetFont() sl@0: { sl@0: } sl@0: sl@0: sl@0: /** sl@0: @see MDirectGdiEngine::SetTextShadowColor() sl@0: */ sl@0: void CSwDirectGdiEngine::SetTextShadowColor(const TRgb& aColor) sl@0: { sl@0: iTextShadowColor = aColor; sl@0: } sl@0: sl@0: /** sl@0: @see MDirectGdiEngine::BeginDrawGlyph() sl@0: */ sl@0: void CSwDirectGdiEngine::BeginDrawGlyph() sl@0: { sl@0: } sl@0: sl@0: /** sl@0: @see MDirectGdiEngine::DrawGlyph() sl@0: @panic DGDIAdapter 56, if an invalid glyph bitmap type is passed in. sl@0: */ sl@0: void CSwDirectGdiEngine::DrawGlyph(const TPoint& aScrPos, const TChar /*aChar*/, const TUint8* aGlyphImage, sl@0: const TGlyphBitmapType aGlyphBitmapType, const TSize& aGlyphImageSize, sl@0: const TRect& aScrClipRect, const DirectGdi::TGraphicsRotation aRotation) sl@0: { sl@0: TPoint pos=aScrPos; sl@0: pos+=iDrawOrigin; sl@0: TRect clipRect=aScrClipRect; sl@0: clipRect.iTl+=iDrawOrigin; sl@0: clipRect.iBr+=iDrawOrigin; sl@0: TRect regionRect(0, 0, 0, 0); sl@0: TInt numRects = iDefaultRegionPtr->Count(); sl@0: for (TInt count = 0; count < numRects; count++) sl@0: { sl@0: // Do the clip rects intersect? sl@0: regionRect = (*iDefaultRegionPtr)[count]; sl@0: if (!regionRect.Intersects(clipRect)) sl@0: { sl@0: // Nothing to draw sl@0: continue; sl@0: } sl@0: // Clip to intersection of two clip rects sl@0: regionRect.Intersection(clipRect); sl@0: sl@0: if (aRotation == DirectGdi::EGraphicsRotationNone) // Horizontal text sl@0: { sl@0: // Do the glyph and the clip rect intersect? sl@0: TRect glyphRect(pos, aGlyphImageSize); sl@0: if (!regionRect.Intersects(glyphRect)) sl@0: { sl@0: // Nothing to draw sl@0: continue; sl@0: } sl@0: // Clip to intersection with glyph bitmap sl@0: regionRect.Intersection(glyphRect); sl@0: sl@0: switch (aGlyphBitmapType) sl@0: { sl@0: case EMonochromeGlyphBitmap: sl@0: { sl@0: DrawBitmapGlyph(pos, aGlyphImage, aGlyphImageSize, regionRect); sl@0: break; sl@0: } sl@0: case EAntiAliasedGlyphBitmap: sl@0: { sl@0: DrawAntiAliasedGlyph(pos, aGlyphImage, aGlyphImageSize, regionRect); sl@0: break; sl@0: } sl@0: case EFourColourBlendGlyphBitmap: sl@0: { sl@0: DrawFourColourGlyph(pos, aGlyphImage, aGlyphImageSize, regionRect); sl@0: break; sl@0: } sl@0: default: sl@0: GRAPHICS_PANIC_ALWAYS(EDirectGdiPanicInvalidGlyphBitmapType); sl@0: } sl@0: } sl@0: else // Vertical text sl@0: { sl@0: /* sl@0: // Do the glyph and the clip rect intersect? sl@0: TRect glyphRect(aPos, aGlyphImageSize); sl@0: if (!regionRect.Intersects(glyphRect)) sl@0: { sl@0: // Nothing to draw sl@0: continue; sl@0: } sl@0: // Clip to intersection with glyph bitmap sl@0: regionRect.Intersection(glyphRect); sl@0: */ sl@0: sl@0: switch (aGlyphBitmapType) sl@0: { sl@0: case EMonochromeGlyphBitmap: sl@0: { sl@0: DrawRotatedBitmapGlyph(pos, aGlyphImage, aGlyphImageSize, regionRect, aRotation); sl@0: break; sl@0: } sl@0: case EAntiAliasedGlyphBitmap: sl@0: { sl@0: DrawRotatedAntiAliasedGlyph(pos, aGlyphImage, aGlyphImageSize, regionRect, aRotation); sl@0: break; sl@0: } sl@0: case EFourColourBlendGlyphBitmap: sl@0: { sl@0: DrawRotatedFourColourGlyph(pos, aGlyphImage, aGlyphImageSize, regionRect, aRotation); sl@0: break; sl@0: } sl@0: default: sl@0: GRAPHICS_PANIC_ALWAYS(EDirectGdiPanicInvalidGlyphBitmapType); sl@0: } sl@0: } sl@0: // Now display it sl@0: iDrawDevice->UpdateRegion(regionRect); sl@0: } sl@0: } sl@0: sl@0: /** sl@0: @see MDirectGdiEngine::EndDrawGlyph() sl@0: */ sl@0: void CSwDirectGdiEngine::EndDrawGlyph() sl@0: { sl@0: } sl@0: sl@0: /** sl@0: Draw a bitmap glyph. sl@0: sl@0: @param aPos Position to start drawing gyph. sl@0: @param aGlyphImage Pointer to the glyph image data. sl@0: @param aGlyphImageSize Glyph image size. sl@0: @param aClipRect Clipping rect. sl@0: */ sl@0: void CSwDirectGdiEngine::DrawBitmapGlyph(const TPoint& aPos, const TUint8* aGlyphImage, sl@0: const TSize& aGlyphImageSize, const TRect& aClipRect) sl@0: { sl@0: // aChar parameter not needed because SW implementation uses the default glyph cache sl@0: // therefore does not need aChar to index its own local cache sl@0: sl@0: /* sl@0: Divert if the character is large. sl@0: Large is defined as wider than 30 bits (a scan line won't fit in a TInt32) sl@0: or greater than 32 bits high (because that's the current array size - could be changed). sl@0: */ sl@0: TInt dataHeight = aGlyphImageSize.iHeight; sl@0: TInt dataLength = aGlyphImageSize.iWidth; sl@0: if (dataLength > 30 || dataHeight > 32) sl@0: { sl@0: DrawLargeBitmapGlyph(aPos, aGlyphImage, aGlyphImageSize, aClipRect); sl@0: return; sl@0: } sl@0: sl@0: TInt bitIndex = 0; sl@0: TInt16 repeatCount = 0; sl@0: TUint32 binaryData[32]; sl@0: TUint32* binaryDataPtr = binaryData; sl@0: TUint32* binaryDataPtrLimit; sl@0: for (TInt glyphLine = 0; glyphLine < dataHeight; glyphLine += repeatCount) // for lines in the glyph bitmap sl@0: { sl@0: repeatCount = Load16(aGlyphImage + (bitIndex >> 3)); sl@0: repeatCount >>= bitIndex & 7; sl@0: TInt multiLineFlag = repeatCount & 1; sl@0: repeatCount >>= 1; sl@0: repeatCount &= 0xf; sl@0: bitIndex += 5; sl@0: binaryDataPtrLimit = binaryData + glyphLine + repeatCount; sl@0: if (multiLineFlag) sl@0: { sl@0: while (binaryDataPtr < binaryDataPtrLimit) sl@0: { sl@0: TInt glyphDataOffsetPtr = TInt(aGlyphImage) + (bitIndex >> 3); sl@0: TUint32* glyphDataWord = (TUint32*)(glyphDataOffsetPtr & ~3); sl@0: TInt bitShift = bitIndex & 7; sl@0: bitShift += (glyphDataOffsetPtr & 3) << 3; sl@0: *binaryDataPtr = (*glyphDataWord++) >> bitShift; sl@0: if (bitShift) sl@0: { sl@0: *binaryDataPtr |= (*glyphDataWord << (32 - bitShift)); sl@0: } sl@0: bitIndex += dataLength; sl@0: binaryDataPtr++; sl@0: } sl@0: } sl@0: else sl@0: { sl@0: TInt glyphDataOffsetPtr = TInt(aGlyphImage) + (bitIndex >> 3); sl@0: TUint32* glyphDataWord = (TUint32*)(glyphDataOffsetPtr & ~3); sl@0: TInt bitShift = bitIndex & 7; sl@0: bitShift += (glyphDataOffsetPtr & 3) << 3; sl@0: TUint32 data = (*glyphDataWord++) >> bitShift; sl@0: if (bitShift) sl@0: { sl@0: data |= (*glyphDataWord << (32 - bitShift)); sl@0: } sl@0: while (binaryDataPtr < binaryDataPtrLimit) sl@0: { sl@0: *binaryDataPtr++ = data; sl@0: } sl@0: bitIndex += dataLength; sl@0: } sl@0: } sl@0: TPoint topLeft(aPos); sl@0: binaryDataPtr = ClipBinaryArray(binaryData, binaryData + dataHeight, dataLength, dataHeight, topLeft, aClipRect); sl@0: if ((dataLength > 0) && (dataHeight > 0)) sl@0: { sl@0: iDrawDevice->WriteBinary(topLeft.iX, topLeft.iY, binaryDataPtr, dataLength, dataHeight, iPenColor, GcDrawMode(iDrawMode) ); sl@0: } sl@0: } sl@0: sl@0: sl@0: /** sl@0: Draw a large bitmap glyph. sl@0: sl@0: @param aPos Position to start drawing gyph. sl@0: @param aGlyphImage Pointer to the glyph image data. sl@0: @param aGlyphImageSize Glyph image size. sl@0: @param aClipRect Clipping rect. sl@0: */ sl@0: void CSwDirectGdiEngine::DrawLargeBitmapGlyph(const TPoint& aPos, const TUint8* aGlyphImage, sl@0: const TSize& aGlyphImageSize, const TRect& aClipRect) sl@0: { sl@0: TPoint printPos(aPos); sl@0: const TInt dataLength = aGlyphImageSize.iWidth; sl@0: const TInt dataHeight = aGlyphImageSize.iHeight; sl@0: TInt bitIndex = 0; sl@0: TInt16 repeatCount = 0; sl@0: TUint32* scanLineBuffer = iDrawDevice->ScanLineBuffer(); sl@0: const TInt scanLineWords = (iDrawDevice->ScanLineBytes()) << 3; sl@0: for (TInt glyphLine = 0; glyphLine < dataHeight; glyphLine += repeatCount) // for lines in the glyph bitmap sl@0: { sl@0: repeatCount = Load16(aGlyphImage + (bitIndex >> 3)); sl@0: repeatCount >>= bitIndex & 7; sl@0: const TInt multiLineFlag = repeatCount & 1; sl@0: repeatCount >>= 1; sl@0: repeatCount &= 0xf; sl@0: bitIndex += 5; sl@0: if (multiLineFlag) sl@0: { sl@0: for (TInt currentLine = 0; currentLine < repeatCount; currentLine++) sl@0: { sl@0: CopyCharLine(scanLineBuffer, scanLineWords, aGlyphImage + (bitIndex >> 3), bitIndex & 7, dataLength); sl@0: OutputCharLineMultiplied(printPos, scanLineBuffer, dataLength, 1, aClipRect); sl@0: bitIndex += dataLength; sl@0: printPos.iY++; sl@0: } sl@0: } sl@0: else sl@0: { sl@0: CopyCharLine(scanLineBuffer, scanLineWords, aGlyphImage + (bitIndex >> 3), bitIndex & 7, dataLength); sl@0: OutputCharLineMultiplied(printPos, scanLineBuffer, dataLength, repeatCount, aClipRect); sl@0: printPos.iY += repeatCount; sl@0: bitIndex += dataLength; sl@0: } sl@0: } sl@0: } sl@0: sl@0: sl@0: /** sl@0: sl@0: */ sl@0: void CSwDirectGdiEngine::CopyCharLine(TUint32* aBinaryDataPtr, TInt aBufferWords, const TUint8* aData, TInt aBitShift, TInt aCharWidth) sl@0: { sl@0: aBitShift &= 7; sl@0: TInt wordsToCopy = (aCharWidth + 31) >> 5; sl@0: if (wordsToCopy > aBufferWords) sl@0: { sl@0: wordsToCopy = aBufferWords; sl@0: } sl@0: TUint32* ptrLimit = aBinaryDataPtr + wordsToCopy; sl@0: TUint32* dataWord = (TUint32*)(TInt(aData) & ~3); sl@0: aBitShift += (TInt(aData) - TInt(dataWord)) << 3; sl@0: while (aBinaryDataPtr < ptrLimit) sl@0: { sl@0: *aBinaryDataPtr = *dataWord++; sl@0: *aBinaryDataPtr >>= aBitShift; sl@0: if (aBitShift) sl@0: { sl@0: *aBinaryDataPtr |= (*dataWord << (32 - aBitShift)); sl@0: } sl@0: aBinaryDataPtr++; sl@0: } sl@0: } sl@0: sl@0: sl@0: /** sl@0: sl@0: */ sl@0: void CSwDirectGdiEngine::OutputCharLineMultiplied(TPoint aPrintPos, TUint32* aBuffer, TInt aDataLength, TInt aNum, const TRect& aClipRect) sl@0: { sl@0: if (aDataLength <= 0) sl@0: { sl@0: return; sl@0: } sl@0: TInt bufferWords = (aDataLength + 31) >> 5; sl@0: TUint32* bufferLimit = aBuffer + bufferWords; sl@0: if (aPrintPos.iX < aClipRect.iTl.iX) sl@0: { sl@0: TInt pixelExcess = aClipRect.iTl.iX - aPrintPos.iX; sl@0: while (pixelExcess >= 32) sl@0: { sl@0: aBuffer++; sl@0: bufferWords--; sl@0: aDataLength -= 32; sl@0: pixelExcess -= 32; sl@0: } sl@0: if (aDataLength <= 0) sl@0: { sl@0: return; sl@0: } sl@0: if (pixelExcess > 0) sl@0: { sl@0: TInt shiftUp = 32 - pixelExcess; sl@0: TUint32* bufferPtr = aBuffer; sl@0: while (bufferPtr < bufferLimit) sl@0: { sl@0: *bufferPtr >>= pixelExcess; sl@0: if (bufferPtr < bufferLimit - 1) sl@0: { sl@0: *bufferPtr |= (*(bufferPtr + 1) << shiftUp); sl@0: } sl@0: bufferPtr++; sl@0: } sl@0: aDataLength -= pixelExcess; sl@0: if (aDataLength <= 0) sl@0: { sl@0: return; sl@0: } sl@0: } sl@0: aPrintPos.iX = aClipRect.iTl.iX; sl@0: } sl@0: if (aPrintPos.iX + aDataLength > aClipRect.iBr.iX) sl@0: { sl@0: TInt pixelExcess = aPrintPos.iX + aDataLength - aClipRect.iBr.iX; sl@0: aDataLength -= pixelExcess; sl@0: if (aDataLength <= 0) sl@0: { sl@0: return; sl@0: } sl@0: } sl@0: while (aNum > 0) sl@0: { sl@0: if ((aPrintPos.iY >= aClipRect.iTl.iY) && (aPrintPos.iY < aClipRect.iBr.iY)) sl@0: { sl@0: iDrawDevice->WriteBinaryLine(aPrintPos.iX, aPrintPos.iY, aBuffer, aDataLength, iPenColor, GcDrawMode(iDrawMode)); sl@0: } sl@0: aPrintPos.iY++; sl@0: aNum--; sl@0: } sl@0: } sl@0: sl@0: sl@0: /** sl@0: Draw a rotated bitmap glyph. sl@0: sl@0: @param aPos Position to start drawing glyph after rotation has been applied. sl@0: @param aGlyphImage Pointer to the glyph image data. sl@0: @param aGlyphImageSize Glyph image size. sl@0: @param aClipRect Clipping rect. sl@0: @param aRotation Rotation specifying how the glyph will be drawn. sl@0: */ sl@0: void CSwDirectGdiEngine::DrawRotatedBitmapGlyph(const TPoint& aPos, const TUint8* aGlyphImage, sl@0: const TSize& aGlyphImageSize, const TRect& aClipRect, const DirectGdi::TGraphicsRotation aRotation) sl@0: { sl@0: TPoint printPos(aPos); sl@0: TInt dataLength = aGlyphImageSize.iWidth; sl@0: TInt dataHeight = aGlyphImageSize.iHeight; sl@0: TInt bitIndex = 0; sl@0: TInt16 repeatCount = 0; sl@0: TInt direction = (aRotation == DirectGdi::EGraphicsRotation270) ? 1 : -1; sl@0: TUint32* scanLineBuffer = iDrawDevice->ScanLineBuffer(); sl@0: TInt scanLineWords = (iDrawDevice->ScanLineBytes()) << 3; sl@0: for (TInt glyphLine = 0; glyphLine < dataHeight; glyphLine += repeatCount) // for lines in the glyph bitmap... sl@0: { sl@0: repeatCount = Load16(aGlyphImage + (bitIndex >> 3)); sl@0: repeatCount >>= bitIndex & 7; sl@0: TInt multiLineFlag = repeatCount & 1; sl@0: repeatCount >>= 1; sl@0: repeatCount &= 0xf; sl@0: bitIndex += 5; sl@0: TInt signedRepeatCount = repeatCount * direction; sl@0: if (multiLineFlag) sl@0: { sl@0: for (TInt currentLine = 0; currentLine < repeatCount; currentLine++) sl@0: { sl@0: CopyCharLine(scanLineBuffer, scanLineWords, aGlyphImage + (bitIndex >> 3), bitIndex & 7, dataLength); sl@0: OutputCharLineVertical(printPos, scanLineBuffer, dataLength, 1, direction, aClipRect); sl@0: bitIndex += dataLength; sl@0: printPos.iX += direction; sl@0: } sl@0: } sl@0: else sl@0: { sl@0: CopyCharLine(scanLineBuffer,scanLineWords, aGlyphImage + (bitIndex >> 3), bitIndex & 7, dataLength); sl@0: OutputCharLineVertical(printPos, scanLineBuffer, dataLength, repeatCount, direction, aClipRect); sl@0: printPos.iX += signedRepeatCount; sl@0: bitIndex += dataLength; sl@0: } sl@0: } sl@0: } sl@0: sl@0: sl@0: /** sl@0: sl@0: */ sl@0: void CSwDirectGdiEngine::OutputCharLineVertical(TPoint aPrintPos, TUint32* aBuffer, TInt aDataLength, sl@0: TInt aNum, TInt aDirection, const TRect& aClipRect) sl@0: { sl@0: // const DirectGdi::TGraphicsRotation rotation = aUp ? DirectGdi::EGraphicsRotation270 : DirectGdi::EGraphicsRotation90; sl@0: // TInt direction = (aRotation == DirectGdi::EGraphicsRotation270) ? 1 : -1; sl@0: if (aDataLength <= 0) sl@0: { sl@0: return; sl@0: } sl@0: TInt bufferWords = (aDataLength + 31) >> 5; sl@0: TUint32* bufferLimit = aBuffer + bufferWords; sl@0: if (aDirection == 1) sl@0: { sl@0: if (aPrintPos.iY >= aClipRect.iBr.iY) sl@0: { sl@0: TInt pixelExcess = aPrintPos.iY - aClipRect.iBr.iY + 1; sl@0: while (pixelExcess >= 32) sl@0: { sl@0: aBuffer++; sl@0: aDataLength -= 32; sl@0: pixelExcess -= 32; sl@0: } sl@0: if (aDataLength <= 0) sl@0: { sl@0: return; sl@0: } sl@0: if (pixelExcess > 0) sl@0: { sl@0: TInt shiftUp = 32 - pixelExcess; sl@0: TUint32* bufferPtr = aBuffer; sl@0: while (bufferPtr < bufferLimit) sl@0: { sl@0: *bufferPtr >>= pixelExcess; sl@0: if (bufferPtr < bufferLimit - 1) sl@0: *bufferPtr |= (*(bufferPtr + 1) << shiftUp); sl@0: bufferPtr++; sl@0: } sl@0: aDataLength -= pixelExcess; sl@0: if (aDataLength <= 0) sl@0: { sl@0: return; sl@0: } sl@0: } sl@0: aPrintPos.iY = aClipRect.iBr.iY - 1; sl@0: } sl@0: if ((aPrintPos.iY - aDataLength) < (aClipRect.iTl.iY - 1)) sl@0: { sl@0: TInt pixelExcess = aClipRect.iTl.iY - 1 - aPrintPos.iY + aDataLength; sl@0: aDataLength -= pixelExcess; sl@0: if (aDataLength <= 0) sl@0: { sl@0: return; sl@0: } sl@0: } sl@0: } sl@0: else sl@0: { sl@0: if (aPrintPos.iY < aClipRect.iTl.iY) sl@0: { sl@0: TInt pixelExcess = aClipRect.iTl.iY - aPrintPos.iY; sl@0: while (pixelExcess >= 32) sl@0: { sl@0: aBuffer++; sl@0: aDataLength -= 32; sl@0: pixelExcess -= 32; sl@0: } sl@0: if (aDataLength <= 0) sl@0: { sl@0: return; sl@0: } sl@0: if (pixelExcess > 0) sl@0: { sl@0: TInt shiftup = 32 - pixelExcess; sl@0: TUint32* bufferptr = aBuffer; sl@0: while (bufferptr < bufferLimit) sl@0: { sl@0: *bufferptr >>= pixelExcess; sl@0: if (bufferptr < bufferLimit - 1) sl@0: *bufferptr |= (*(bufferptr + 1) << shiftup); sl@0: bufferptr++; sl@0: } sl@0: aDataLength -= pixelExcess; sl@0: if (aDataLength <= 0) sl@0: { sl@0: return; sl@0: } sl@0: } sl@0: aPrintPos.iY = aClipRect.iTl.iY; sl@0: } sl@0: if (aPrintPos.iY + aDataLength > aClipRect.iBr.iY) sl@0: { sl@0: TInt pixelExcess = aPrintPos.iY + aDataLength - aClipRect.iBr.iY; sl@0: aDataLength -= pixelExcess; sl@0: if (aDataLength <= 0) sl@0: { sl@0: return; sl@0: } sl@0: } sl@0: } sl@0: CGraphicsContext::TDrawMode drawMode = GcDrawMode(iDrawMode); sl@0: while (aNum > 0) sl@0: { sl@0: if ((aPrintPos.iX >= aClipRect.iTl.iX) && (aPrintPos.iX < aClipRect.iBr.iX)) sl@0: iDrawDevice->WriteBinaryLineVertical(aPrintPos.iX, aPrintPos.iY, aBuffer, aDataLength, iPenColor, drawMode, (aDirection == 1)); sl@0: aPrintPos.iX += aDirection; sl@0: aNum--; sl@0: } sl@0: } sl@0: sl@0: sl@0: /** sl@0: Draw an antialiased glyph. sl@0: sl@0: @param aPos Position to start drawing gyph. sl@0: @param aGlyphImage Pointer to the glyph image data. sl@0: @param aGlyphImageSize Glyph image size. sl@0: @param aClipRect Clipping rect. sl@0: */ sl@0: void CSwDirectGdiEngine::DrawAntiAliasedGlyph(const TPoint& aPos, const TUint8* aGlyphImage, sl@0: const TSize& aGlyphImageSize, const TRect& aClipRect) sl@0: { sl@0: const TInt topRow = Max(0, aClipRect.iTl.iY - aPos.iY); sl@0: const TInt bottomRow = Min(aGlyphImageSize.iHeight, aClipRect.iBr.iY - aPos.iY); sl@0: const TInt leftCol = Max(0, aClipRect.iTl.iX - aPos.iX); sl@0: const TInt rightCol = Min(aGlyphImageSize.iWidth, aClipRect.iBr.iX - aPos.iX); sl@0: const TUint8* p = aGlyphImage + (topRow * aGlyphImageSize.iWidth) + leftCol; sl@0: const TInt x = aPos.iX + leftCol; sl@0: TInt y = aPos.iY + topRow; sl@0: const TInt cols = rightCol - leftCol; sl@0: sl@0: for (TInt row = topRow; row < bottomRow; row++, p += aGlyphImageSize.iWidth, y++) sl@0: { sl@0: iDrawDevice->WriteRgbAlphaMulti(x, y, cols, iPenColor, p); sl@0: } sl@0: } sl@0: sl@0: sl@0: /** sl@0: Draw a rotated antialiased glyph. sl@0: sl@0: @param aPos Position to start drawing gyph after rotation has been applied. sl@0: @param aGlyphImage Pointer to the glyph image data. sl@0: @param aGlyphImageSize Glyph image size. sl@0: @param aClipRect Clipping rect. sl@0: @param aRotation Rotation specifying how the glyph will be drawn. sl@0: */ sl@0: void CSwDirectGdiEngine::DrawRotatedAntiAliasedGlyph(const TPoint& aPos, const TUint8* aGlyphImage, sl@0: const TSize& aGlyphImageSize, const TRect& aClipRect, const DirectGdi::TGraphicsRotation aRotation) sl@0: { sl@0: const int KBufferSize = 32; sl@0: TUint8 maskBuffer[KBufferSize]; sl@0: int topRow = 0; sl@0: int bottomRow = 0; sl@0: int leftCol = 0; sl@0: int rightCol = 0; sl@0: const TUint32 penColor = iPenColor.Internal(); sl@0: const TUint32 brushColor = iBrushColor.Internal(); sl@0: sl@0: if (aRotation == DirectGdi::EGraphicsRotation270) sl@0: { sl@0: topRow = Max(0, aClipRect.iTl.iX - aPos.iX); sl@0: bottomRow = Min(aGlyphImageSize.iHeight, aClipRect.iBr.iX - aPos.iX); sl@0: leftCol = Max(0, aPos.iY - aClipRect.iBr.iY + 1); sl@0: rightCol = Min(aGlyphImageSize.iWidth, aPos.iY - aClipRect.iTl.iY + 1); sl@0: TInt y = aPos.iY - (rightCol - 1); sl@0: for (TInt col = rightCol - 1; col >= leftCol; col--, y++) sl@0: { sl@0: TInt x = aPos.iX + topRow; sl@0: for (TInt row = topRow; row < bottomRow; row += KBufferSize, x += KBufferSize) sl@0: { sl@0: TInt length = KBufferSize; sl@0: if (length > bottomRow - row) sl@0: { sl@0: length = bottomRow - row; sl@0: } sl@0: const TUint8* p = aGlyphImage + row * aGlyphImageSize.iWidth + col; sl@0: for (TInt i = 0; i < length; i++, p += aGlyphImageSize.iWidth) sl@0: { sl@0: maskBuffer[i] = *p; sl@0: } sl@0: iDrawDevice->WriteRgbAlphaMulti(x, y, length, iPenColor, maskBuffer); sl@0: } sl@0: } sl@0: } sl@0: else sl@0: { sl@0: topRow = Max(0, aPos.iX - aClipRect.iBr.iX + 1); sl@0: bottomRow = Min(aGlyphImageSize.iHeight, aPos.iX - aClipRect.iTl.iX + 1); sl@0: leftCol = Max(0, aClipRect.iTl.iY - aPos.iY); sl@0: rightCol = Min(aGlyphImageSize.iWidth, aClipRect.iBr.iY - aPos.iY); sl@0: int y = aPos.iY + leftCol; sl@0: for (TInt col = leftCol; col < rightCol; col++, y++) sl@0: { sl@0: TInt x = aPos.iX - (bottomRow - 1); sl@0: for (TInt row = bottomRow; row > topRow; row -= KBufferSize, x += KBufferSize) sl@0: { sl@0: int length = KBufferSize; sl@0: if (length > row - topRow) sl@0: length = row - topRow; sl@0: const TUint8* p = aGlyphImage + (row - 1) * aGlyphImageSize.iWidth + col; sl@0: for (TInt i = 0; i < length; i++, p -= aGlyphImageSize.iWidth) sl@0: { sl@0: maskBuffer[i] = *p; sl@0: } sl@0: iDrawDevice->WriteRgbAlphaMulti(x, y, length, iPenColor, maskBuffer); sl@0: } sl@0: } sl@0: } sl@0: } sl@0: sl@0: sl@0: /** sl@0: Draw a four colour glyph. sl@0: sl@0: @param aPos Position to start drawing gyph. sl@0: @param aGlyphImage Pointer to the glyph image data. sl@0: @param aGlyphImageSize Glyph image size. sl@0: @param aClipRect Clipping rect. sl@0: */ sl@0: void CSwDirectGdiEngine::DrawFourColourGlyph(const TPoint& aPos, const TUint8* aGlyphImage, sl@0: const TSize& aGlyphImageSize, const TRect& aClipRect) sl@0: { sl@0: const TInt topRow = Max(0, aClipRect.iTl.iY - aPos.iY); sl@0: const TInt bottomRow = Min(aGlyphImageSize.iHeight, aClipRect.iBr.iY - aPos.iY); sl@0: const TInt leftCol = Max(0, aClipRect.iTl.iX - aPos.iX); sl@0: const TInt rightCol = Min(aGlyphImageSize.iWidth, aClipRect.iBr.iX - aPos.iX); sl@0: const TUint8* p = aGlyphImage + (topRow * aGlyphImageSize.iWidth) + leftCol; sl@0: const TInt x = aPos.iX + leftCol; sl@0: TInt y = aPos.iY + topRow; sl@0: const TInt cols = rightCol - leftCol; sl@0: const TUint32 penColor = iPenColor.Internal(); sl@0: const TUint32 shadowColor = iTextShadowColor.Internal(); sl@0: const TUint32 brushColor = iBrushColor.Internal(); sl@0: sl@0: MOutlineAndShadowBlend* outlineAndShadow = NULL; sl@0: const TInt err = iDrawDevice->GetInterface(KOutlineAndShadowInterfaceID, reinterpret_cast (outlineAndShadow)); sl@0: if (err == KErrNone) sl@0: { sl@0: //There is a support for the interface with KOutlineAndShadowInterface id. sl@0: for (TInt row = topRow; row < bottomRow; row++, p += aGlyphImageSize.iWidth, y++) sl@0: { sl@0: outlineAndShadow->WriteRgbOutlineAndShadow(x, y, cols, penColor, shadowColor, brushColor, p); sl@0: } sl@0: } sl@0: else sl@0: { sl@0: // Assert if MOutlineAndShadowBlend interface is not implemented sl@0: GRAPHICS_ASSERT_DEBUG(outlineAndShadow, EDirectGdiPanicInvalidInterfaceHandle); sl@0: } sl@0: } sl@0: sl@0: sl@0: /** sl@0: Draw a rotated four colour glyph. sl@0: sl@0: @param aPos Position to start drawing gyph after rotation has been applied. sl@0: @param aGlyphImage Pointer to the glyph image data. sl@0: @param aGlyphImageSize Glyph image size. sl@0: @param aClipRect Clipping rect. sl@0: @param aRotation Rotation specifying how the glyph will be drawn. sl@0: */ sl@0: void CSwDirectGdiEngine::DrawRotatedFourColourGlyph(const TPoint& aPos, const TUint8* aGlyphImage, const TSize& aGlyphImageSize, sl@0: const TRect& aClipRect, const DirectGdi::TGraphicsRotation aRotation) sl@0: { sl@0: const int KBufferSize = 32; sl@0: TUint8 maskBuffer[KBufferSize]; sl@0: int topRow = 0; sl@0: int bottomRow = 0; sl@0: int leftCol = 0; sl@0: int rightCol = 0; sl@0: const TUint32 penColor = iPenColor.Internal(); sl@0: const TUint32 shadowColor = iTextShadowColor.Internal(); sl@0: const TUint32 brushColor = iBrushColor.Internal(); sl@0: sl@0: MOutlineAndShadowBlend* outlineAndShadow = NULL; sl@0: TInt err = iDrawDevice->GetInterface(KOutlineAndShadowInterfaceID, reinterpret_cast (outlineAndShadow)); sl@0: if(err != KErrNone) sl@0: { sl@0: // Assert if MOutlineAndShadowBlend interface is not implemented sl@0: GRAPHICS_ASSERT_DEBUG(outlineAndShadow, EDirectGdiPanicInvalidInterfaceHandle); sl@0: } sl@0: sl@0: if (aRotation == DirectGdi::EGraphicsRotation270) sl@0: { sl@0: topRow = Max(0, aClipRect.iTl.iX - aPos.iX); sl@0: bottomRow = Min(aGlyphImageSize.iHeight, aClipRect.iBr.iX - aPos.iX); sl@0: leftCol = Max(0, aPos.iY - aClipRect.iBr.iY + 1); sl@0: rightCol = Min(aGlyphImageSize.iWidth, aPos.iY - aClipRect.iTl.iY + 1); sl@0: TInt y = aPos.iY - (rightCol - 1); sl@0: for (TInt col = rightCol - 1; col >= leftCol; col--, y++) sl@0: { sl@0: TInt x = aPos.iX + topRow; sl@0: for (TInt row = topRow; row < bottomRow; row += KBufferSize, x += KBufferSize) sl@0: { sl@0: TInt length = KBufferSize; sl@0: if (length > bottomRow - row) sl@0: { sl@0: length = bottomRow - row; sl@0: } sl@0: const TUint8* p = aGlyphImage + row * aGlyphImageSize.iWidth + col; sl@0: for (TInt i = 0; i < length; i++, p += aGlyphImageSize.iWidth) sl@0: { sl@0: maskBuffer[i] = *p; sl@0: } sl@0: //There is a support for the interface with KOutlineAndShadowInterface id. sl@0: outlineAndShadow->WriteRgbOutlineAndShadow(x, y, length, penColor, shadowColor, brushColor, maskBuffer); sl@0: } sl@0: } sl@0: } sl@0: else sl@0: { sl@0: topRow = Max(0, aPos.iX - aClipRect.iBr.iX + 1); sl@0: bottomRow = Min(aGlyphImageSize.iHeight, aPos.iX - aClipRect.iTl.iX + 1); sl@0: leftCol = Max(0, aClipRect.iTl.iY - aPos.iY); sl@0: rightCol = Min(aGlyphImageSize.iWidth, aClipRect.iBr.iY - aPos.iY); sl@0: int y = aPos.iY + leftCol; sl@0: for (TInt col = leftCol; col < rightCol; col++, y++) sl@0: { sl@0: TInt x = aPos.iX - (bottomRow - 1); sl@0: for (TInt row = bottomRow; row > topRow; row -= KBufferSize, x += KBufferSize) sl@0: { sl@0: int length = KBufferSize; sl@0: if (length > row - topRow) sl@0: length = row - topRow; sl@0: const TUint8* p = aGlyphImage + (row - 1) * aGlyphImageSize.iWidth + col; sl@0: for (TInt i = 0; i < length; i++, p -= aGlyphImageSize.iWidth) sl@0: { sl@0: maskBuffer[i] = *p; sl@0: } sl@0: //There is a support for the interface with KOutlineAndShadowInterface id. sl@0: outlineAndShadow->WriteRgbOutlineAndShadow(x, y, length, penColor, shadowColor, brushColor, maskBuffer); sl@0: } sl@0: } sl@0: } sl@0: } sl@0: sl@0: sl@0: /** sl@0: Helper function to clip the array to the clip rect. sl@0: sl@0: @param aArray Start of array of data to be clipped. sl@0: @param aArrayLimit End of array of data to be clipped. sl@0: @param aDataWd Length of data. sl@0: @param aDataHt Height of data. sl@0: @param aPos Position to start drawing from. sl@0: @param aClipRect Rectangle to clip data array to. sl@0: sl@0: @return Pointer to array of clipped data. sl@0: */ sl@0: TUint32* CSwDirectGdiEngine::ClipBinaryArray(TUint32* aArray, TUint32* aArrayLimit, TInt& aDataWd, TInt& aDataHt, TPoint& aPos, const TRect& aClipRect) sl@0: { sl@0: TUint32* arrayPtr = aArray; sl@0: TInt clipDiff = aClipRect.iTl.iX - aPos.iX; sl@0: if (clipDiff > 0) sl@0: { sl@0: while (arrayPtr < aArrayLimit) sl@0: { sl@0: *arrayPtr++ >>= clipDiff; sl@0: } sl@0: aDataWd -= clipDiff; sl@0: aPos.iX = aClipRect.iTl.iX; sl@0: arrayPtr = aArray; sl@0: } sl@0: if ((aPos.iX + aDataWd > aClipRect.iBr.iX) && (aDataWd > 0)) sl@0: { sl@0: aDataWd = aClipRect.iBr.iX - aPos.iX; sl@0: } sl@0: clipDiff = aClipRect.iTl.iY - aPos.iY; sl@0: if (clipDiff > 0) sl@0: { sl@0: aDataHt -= clipDiff; sl@0: arrayPtr += clipDiff; sl@0: aPos.iY = aClipRect.iTl.iY; sl@0: } sl@0: if (((aPos.iY + aDataHt) > (aClipRect.iBr.iY)) && (aDataHt > 0)) sl@0: { sl@0: aDataHt = aClipRect.iBr.iY - aPos.iY; sl@0: } sl@0: return arrayPtr; sl@0: }