@ -346,7 +346,12 @@ void plFont::IRenderString( plMipmap *mip, UInt16 x, UInt16 y, const wchar_t *st
if ( fRenderInfo . fFlags & kRenderIntoAlpha )
if ( fRenderInfo . fFlags & kRenderIntoAlpha )
{
{
if ( fRenderInfo . fFlags & kRenderAlphaPremultiplied )
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 )
else if ( ( fRenderInfo . fColor & 0xff000000 ) ! = 0xff000000 )
fRenderInfo . fRenderFunc = & plFont : : IRenderChar8To32Alpha ;
fRenderInfo . fRenderFunc = & plFont : : IRenderChar8To32Alpha ;
else
else
@ -1059,8 +1064,8 @@ void plFont::IRenderChar8To32AlphaPremultiplied( const plFont::plCharacter &c )
srcA = ( UInt8 ) ( ( fRenderInfo . fColor > > 24 ) & 0x000000ff ) ;
srcA = ( UInt8 ) ( ( fRenderInfo . fColor > > 24 ) & 0x000000ff ) ;
srcR = ( UInt8 ) ( ( fRenderInfo . fColor > > 16 ) & 0x000000ff ) ;
srcR = ( UInt8 ) ( ( fRenderInfo . fColor > > 16 ) & 0x000000ff ) ;
srcG = ( UInt8 ) ( ( fRenderInfo . fColor > > 8 ) & 0x000000ff ) ;
srcG = ( UInt8 ) ( ( fRenderInfo . fColor > > 8 ) & 0x000000ff ) ;
srcB = ( UInt8 ) ( ( fRenderInfo . fColor ) & 0x000000ff ) ;
srcB = ( UInt8 ) ( ( fRenderInfo . fColor ) & 0x000000ff ) ;
y = fRenderInfo . fClipRect . fY - fRenderInfo . fY + ( Int16 ) c . fBaseline ;
y = fRenderInfo . fClipRect . fY - fRenderInfo . fY + ( Int16 ) c . fBaseline ;
if ( y < 0 )
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 )
void plFont : : IRenderCharNull ( const plCharacter & c )
{
{