diff --git a/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/PubUtilLib/plGImage/plFont.cpp b/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/PubUtilLib/plGImage/plFont.cpp index ebc8fb6d..f5761216 100644 --- a/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/PubUtilLib/plGImage/plFont.cpp +++ b/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/PubUtilLib/plGImage/plFont.cpp @@ -346,7 +346,12 @@ void plFont::IRenderString( plMipmap *mip, UInt16 x, UInt16 y, const wchar_t *st if( fRenderInfo.fFlags & kRenderIntoAlpha ) { if( fRenderInfo.fFlags & kRenderAlphaPremultiplied ) - fRenderInfo.fRenderFunc = &plFont::IRenderChar8To32AlphaPremultiplied; + { + if (1)//( ( fRenderInfo.fColor & 0x00ffffff ) == 0x00ffffff ) //FIXME + fRenderInfo.fRenderFunc = &plFont::IRenderChar8To32AlphaPremShadow; + else + fRenderInfo.fRenderFunc = &plFont::IRenderChar8To32AlphaPremultiplied; + } else if( ( fRenderInfo.fColor & 0xff000000 ) != 0xff000000 ) fRenderInfo.fRenderFunc = &plFont::IRenderChar8To32Alpha; else @@ -1059,8 +1064,8 @@ void plFont::IRenderChar8To32AlphaPremultiplied( const plFont::plCharacter &c ) srcA = (UInt8)(( fRenderInfo.fColor >> 24 ) & 0x000000ff); srcR = (UInt8)(( fRenderInfo.fColor >> 16 ) & 0x000000ff); - srcG = (UInt8)(( fRenderInfo.fColor >> 8 ) & 0x000000ff); - srcB = (UInt8)(( fRenderInfo.fColor ) & 0x000000ff); + srcG = (UInt8)(( fRenderInfo.fColor >> 8 ) & 0x000000ff); + srcB = (UInt8)(( fRenderInfo.fColor ) & 0x000000ff); y = fRenderInfo.fClipRect.fY - fRenderInfo.fY + (Int16)c.fBaseline; if( y < 0 ) @@ -1093,6 +1098,81 @@ void plFont::IRenderChar8To32AlphaPremultiplied( const plFont::plCharacter &c ) } } +void plFont::IRenderChar8To32AlphaPremShadow( const plFont::plCharacter &c ) +{ + UInt32 *destPtr, *destBasePtr = (UInt32 *)( fRenderInfo.fDestPtr - c.fBaseline * fRenderInfo.fDestStride ); + Int16 x, y, thisHeight, xstart, thisWidth; + UInt8 srcA, srcR, srcG, srcB; + + + // Unfortunately for some fonts, their right kern value actually is + // farther left than the right edge of the bitmap (think of overlapping + // script fonts). Ideally, we should store the actual width of each char's + // bitmap and use that here. However, it really shouldn't make too big of a + // difference, especially since the dest pixels that we end up overlapping + // should already be in the cache. If it does, time to upgrade the font + // format (again) + thisWidth = fWidth + 2;// + (Int32)c.fRightKern; + if( thisWidth >= fRenderInfo.fMaxWidth ) + thisWidth = fRenderInfo.fMaxWidth; + + xstart = fRenderInfo.fClipRect.fX - fRenderInfo.fX; + if( xstart < -2 ) + xstart = -2; + + srcA = (UInt8)(( fRenderInfo.fColor >> 24 ) & 0x000000ff); + srcR = (UInt8)(( fRenderInfo.fColor >> 16 ) & 0x000000ff); + srcG = (UInt8)(( fRenderInfo.fColor >> 8 ) & 0x000000ff); + srcB = (UInt8)(( fRenderInfo.fColor ) & 0x000000ff); + + static const UInt32 kernel[5][5] = { + {1, 2, 2, 2, 1}, + {1, 13, 13, 13, 1}, + {1, 10, 10, 10, 1}, + {1, 7, 7, 7, 1}, + {1, 1, 1, 1, 1} + }; + + UInt32 clamp = 220 - ((2 * srcR + 4 * srcG + srcB) >> 4); + + y = fRenderInfo.fClipRect.fY - fRenderInfo.fY + (Int16)c.fBaseline; + if( y < -2 ) + y = -2; + destBasePtr = (UInt32 *)( (UInt8 *)destBasePtr + y*fRenderInfo.fDestStride ); + + thisHeight = fRenderInfo.fMaxHeight + (Int16)c.fBaseline; + if( thisHeight > (Int16)c.fHeight + 2 ) + thisHeight = (Int16)c.fHeight + 2; + + for( ; y < thisHeight; y++ ) + { + destPtr = destBasePtr; + for( x = xstart; x < thisWidth; x++ ) + { + UInt32 sa = 0; + for (Int32 i = -2; i <= 2; i++) { + for (Int32 j = -2; j <= 2; j++) { + UInt32 m = kernel[j+2][i+2]; + if (m != 0) + sa += m * IGetCharPixel(c, x+i, y+j); + } + } + sa = (sa * clamp) >> 13; + if (sa > clamp) + sa = clamp; + UInt32 a = IGetCharPixel(c, x, y); + if (srcA != 0xff) + a = (srcA * a + 127) / 255; + UInt32 ta = a + sa - ((a*sa + 127) / 255); + if (ta > (destPtr[ x ] >> 24)) + destPtr[ x ] = ( ta << 24 ) | (((srcR * a + 127) / 255) << 16) | + (((srcG * a + 127) / 255) << 8) | + (((srcB * a + 127) / 255) << 0); + } + destBasePtr = (UInt32 *)( (UInt8 *)destBasePtr + fRenderInfo.fDestStride ); + } +} + void plFont::IRenderCharNull( const plCharacter &c ) { diff --git a/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/PubUtilLib/plGImage/plFont.h b/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/PubUtilLib/plGImage/plFont.h index 11e38ca3..ff69be5b 100644 --- a/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/PubUtilLib/plGImage/plFont.h +++ b/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/PubUtilLib/plGImage/plFont.h @@ -233,8 +233,15 @@ class plFont : public hsKeyedObject void IRenderChar8To32Alpha( const plCharacter &c ); void IRenderChar8To32FullAlpha( const plCharacter &c ); void IRenderChar8To32AlphaPremultiplied( const plCharacter &c ); + void IRenderChar8To32AlphaPremShadow( const plCharacter &c ); void IRenderCharNull( const plCharacter &c ); + UInt32 IGetCharPixel( const plCharacter &c, Int32 x, Int32 y ) + { + // only for 8-bit characters + return (x < 0 || y < 0 || (UInt32)x >= fWidth || (UInt32)y >= c.fHeight) ? 0 : *(fBMapData + c.fBitmapOff + y*fWidth + x); + } + public: plFont();