Skip to content

Commit

Permalink
Add initial support for LCD font quality
Browse files Browse the repository at this point in the history
  • Loading branch information
hughsando committed Mar 28, 2024
1 parent 4e39263 commit c74fec0
Show file tree
Hide file tree
Showing 18 changed files with 372 additions and 104 deletions.
14 changes: 14 additions & 0 deletions include/nme/Pixel.h
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,15 @@ struct BGRA

inline BGRA() { }
inline BGRA(int inRGBA) { ival = inRGBA; }
inline BGRA(int inRGBA,bool withPrem) {
if (withPrem && PREM) {
a = (inRGBA>>24);
r = gPremAlphaLut[a][(inRGBA>>16)&0xff ];
g = gPremAlphaLut[a][(inRGBA>>8)&0xff ];
b = gPremAlphaLut[a][(inRGBA)&0xff ];
} else
ival = inRGBA;
}
inline BGRA(int inRGB,int inA) { ival = (inRGB & 0xffffff) | (inA<<24); }
inline BGRA(int inRGB,float inA)
{
Expand All @@ -109,6 +118,7 @@ struct BGRA
inline int getB() const { return PREM ? gUnPremAlphaLut[a][b] : b; }
inline int getLuma() const { return PREM ? gUnPremAlphaLut[a][(r+(g<<1)+b)>>2] : (r+(g<<1)+b)>>2; }

inline void setAlphaOnly(Uint8 val) { a = val; }
inline void setAlpha(Uint8 val)
{
if (PREM && val!=a)
Expand Down Expand Up @@ -198,6 +208,7 @@ struct RGB
inline int getB() const { return b; }


inline void setAlphaOnly(Uint8 val) { }
inline void setAlpha(Uint8 val) { }
inline void setLuma(Uint8 val) { r = g = b = val; }

Expand Down Expand Up @@ -268,6 +279,7 @@ struct AlphaPixel



inline void setAlphaOnly(Uint8 val) { a = val; }
inline void setAlpha(Uint8 val) { a = val; }
inline void setLuma(Uint8 val) { }

Expand Down Expand Up @@ -302,6 +314,7 @@ struct LumaPixel



inline void setAlphaOnly(int val) { }
inline void setAlpha(int val) { }
inline void setLuma(int val) { luma = val; }

Expand Down Expand Up @@ -335,6 +348,7 @@ struct LumaAlphaPixel



inline void setAlphaOnly(Uint8 val) { a = val; }
inline void setAlpha(Uint8 val) { a = val; }
inline void setLuma(Uint8 val) { luma = val; }

Expand Down
2 changes: 2 additions & 0 deletions project/include/Display.h
Original file line number Diff line number Diff line change
Expand Up @@ -408,8 +408,10 @@ class Stage : public DisplayObjectContainer
virtual void RenderStage();
virtual void EndRenderStage();
virtual void ResizeWindow(int inWidth, int inHeight) {};
virtual HardwareRenderer *getHardwareRenderer();

virtual bool isOpenGL() const = 0;
virtual bool hasHardwareLcdFonts() const;
virtual int getWindowFrameBufferId() { return 0; };

void SetEventHandler(EventHandler inHander,void *inUserData);
Expand Down
2 changes: 1 addition & 1 deletion project/include/Font.h
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ class FontFace
virtual void UpdateMetrics(TextLineMetrics &ioMetrics)=0;
virtual int Height()=0;
virtual bool IsNative() { return false; }
virtual bool WantRGB() { return false; }
virtual PixelFormat getImageFormat() const { return pfAlpha; }

};

Expand Down
3 changes: 3 additions & 0 deletions project/include/Graphics.h
Original file line number Diff line number Diff line change
Expand Up @@ -408,6 +408,9 @@ enum BlendMode
bmTintedInner,
// Used for rendering coloured tiles, with add
bmTintedAdd,

// Used for rendering ClearType text
bmComponentAlpha,
};

class ColorTransform
Expand Down
8 changes: 7 additions & 1 deletion project/include/HardwareImpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,9 @@ enum
PROG_COLOUR_OFFSET = 0x0080,
PROG_4D_INPUT = 0x0100,
PROG_PREM_ALPHA = 0x0200,
PROG_COMP_ALPHA = 0x0400,

PROG_COUNT = 0x0400,
PROG_COUNT = 0x0800,
};

inline unsigned int getProgId( const DrawElement &element, const ColorTransform *ctrans)
Expand Down Expand Up @@ -58,6 +59,11 @@ inline unsigned int getProgId( const DrawElement &element, const ColorTransform
if (ctrans && ctrans->HasOffset())
progId |= PROG_COLOUR_OFFSET;
}
if (element.mBlendMode == bmComponentAlpha)
{
progId |= PROG_COMP_ALPHA;
}


return progId;
}
Expand Down
15 changes: 14 additions & 1 deletion project/src/common/ExternalInterface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1803,7 +1803,20 @@ bool nme_stage_is_opengl(value inStage)
return false;
}
DEFINE_PRIME1(nme_stage_is_opengl);


bool nme_stage_has_hardware_lcd_fonts(value inStage)
{
Stage *stage;
if (AbstractToObject(inStage,stage))
{
return stage->hasHardwareLcdFonts();
}
return false;
}
DEFINE_PRIME1(nme_stage_has_hardware_lcd_fonts);




namespace nme { void AndroidRequestRender(); }
void nme_stage_request_render()
Expand Down
6 changes: 4 additions & 2 deletions project/src/common/Font.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ class CFFIFont : public FontFace
mIsRGB = val_bool( val_field(inHandle, _id_isRGB) );
}

bool WantRGB() { return true; }
PixelFormat getImageFormat() const { return pfBGRA; }

bool GetGlyphInfo(int inChar, int &outW, int &outH, int &outAdvance,
int &outOx, int &outOy)
Expand Down Expand Up @@ -222,7 +222,7 @@ Tile Font::GetGlyph(int inCharacter,int &outAdvance)
int w = h;
while(w<orig_w)
w*=2;
PixelFormat pf = mFace->WantRGB() ? pfBGRA : pfAlpha;
PixelFormat pf = mFace->getImageFormat();
Tilesheet *sheet = new Tilesheet(w,h,pf,true);
sheet->GetSurface().Clear(0);
mCurrentSheet = mSheets.size();
Expand All @@ -247,6 +247,7 @@ Tile Font::GetGlyph(int inCharacter,int &outAdvance)
RenderTarget target = tile.mSurface->BeginRender(tile.mRect);
if (use_default)
{
// TODO - non-alpha images
for(int y=0; y<target.mRect.h; y++)
{
uint8 *dest = (uint8 *)target.Row(y + target.mRect.y) + target.mRect.x;
Expand All @@ -258,6 +259,7 @@ Tile Font::GetGlyph(int inCharacter,int &outAdvance)
mFace->RenderGlyph(inCharacter,target);

tile.mSurface->EndRender();

outAdvance = glyph.advance;
return tile;
}
Expand Down
17 changes: 17 additions & 0 deletions project/src/common/Stage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,23 @@ void Stage::SetNextWakeDelay(double inNextWake)
mNextWake = inNextWake + GetTimeStamp();
}

HardwareRenderer *Stage::getHardwareRenderer()
{
Surface *surface = GetPrimarySurface();
if (!surface)
return nullptr;
return surface->GetHardwareRenderer();
}


bool Stage::hasHardwareLcdFonts() const
{
HardwareRenderer *hw = (const_cast<Stage *>(this))->getHardwareRenderer();
if (!hw)
return false;
return hw->supportsComponentAlpha();
}

void Stage::SetFocusObject(DisplayObject *inObj,FocusSource inSource,int inKey)
{
if (inObj==mFocusObject)
Expand Down
85 changes: 84 additions & 1 deletion project/src/common/SurfaceBlit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,18 @@ struct NullMask
inline uint8 MaskAlpha(const ARGB &inRGB) const { return inRGB.a; }
inline uint8 MaskAlpha(const BGRPremA &inRGB) const { return inRGB.a; }
inline uint8 MaskAlpha(const RGB &inRGB) const { return 255; }

template<typename SRC>
void maskComponentMask(const SRC &inRGB, RGB &outRGB) const
{
/*
outRGB.r = inRGB.getR();
outRGB.g = inRGB.getG();
outRGB.b = inRGB.getB();
*/
}
inline void maskComponentMask(const RGB &inRGB, RGB &outRGB) const { outRGB = inRGB; }

template<typename T>
T Mask(T inT) const { return inT; }
};
Expand Down Expand Up @@ -55,6 +67,24 @@ struct ImageMask
return a;
}

inline void maskComponentMask(const RGB &inRGB, RGB &outRgb) const
{
Uint8 *lut = gPremAlphaLut[*mRow];
outRgb.r = lut[inRGB.r];
outRgb.g = lut[inRGB.g];
outRgb.b = lut[inRGB.b];
}

template<typename T>
inline void maskComponentMask(const T &inPixel, RGB &outRgb) const
{
/*
Uint8 *lut = gPremAlphaLut[*mRow];
outRgb.r = lut[inPixel.getR()];
outRgb.g = lut[inPixel.getG()];
outRgb.b = lut[inPixel.getB()];
*/
}

inline AlphaPixel Mask(const AlphaPixel &inA) const
{
Expand Down Expand Up @@ -514,13 +544,43 @@ template<typename DEST, typename SRC> void ApplyInner(DEST &ioDest, SRC inSrc)
}
}

template<typename DEST> void ApplyComponentAlpha(DEST &ioDest, RGB rgbMask, BGRPremA colour)
{
int outA = std::max(std::max(rgbMask.g,rgbMask.b),rgbMask.r);
if ( outA > 2)
{
int dra = ioDest.getRAlpha();
int dga = ioDest.getGAlpha();
int dba = ioDest.getBAlpha();

ioDest.setAlphaOnly( std::max(outA, ioDest.getAlpha() ) );

{
int notA = 256-rgbMask.r;
ioDest.setRAlpha( ((dra*notA +colour.r*rgbMask.r )>>8) );
}
{
int notA = 256-rgbMask.g;
ioDest.setGAlpha( ((dga*notA +colour.g*rgbMask.g )>>8) );
}
{
int notA = 256-rgbMask.b;
ioDest.setBAlpha( ((dba*notA + colour.b*rgbMask.b )>>8) );
}
}

}







template<typename DEST, typename SOURCE, typename MASK>
void TBlitBlend( const DEST &outDest, SOURCE &inSrc,const MASK &inMask,
int inX, int inY, const Rect &inSrcRect, BlendMode inMode)
int inX, int inY, const Rect &inSrcRect, BlendMode inMode,
BGRPremA tint=0xffffffff)
{
for(int y=0;y<inSrcRect.h;y++)
{
Expand Down Expand Up @@ -571,6 +631,19 @@ void TBlitBlend( const DEST &outDest, SOURCE &inSrc,const MASK &inMask,
}
break;

case bmComponentAlpha:
{
RGB rgb;
for(int x=0;x<inSrcRect.w;x++)
{
typename DEST::Pixel &dest = outDest.Next();
inMask.maskComponentMask(inSrc.Next(),rgb);
ApplyComponentAlpha(dest,rgb,tint);
}
}
break;


case bmNormal:
case bmTinted:
case bmTintedAdd:
Expand Down Expand Up @@ -652,6 +725,16 @@ void TBlitRgb(const DEST &dest, int dx, int dy, const SimpleSurface *inSrc, Rect
else
TBlitBlend( dest, src, NullMask(), dx, dy, src_rect, bmAdd );
}
else if (inBlend==bmComponentAlpha)
{
BGRPremA tint(inTint,true);
ImageSource<RGB> src(inSrc->GetBase(),inSrc->GetStride());

if (inMask)
TBlitBlend( dest, src, ImageMask(*inMask), dx, dy, src_rect, bmComponentAlpha, tint );
else
TBlitBlend( dest, src, NullMask(), dx, dy, src_rect, bmComponentAlpha, tint );
}
else
{
switch(inSrc->Format())
Expand Down
3 changes: 2 additions & 1 deletion project/src/common/TextField.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1891,7 +1891,7 @@ void TextField::Render( const RenderTarget &inTarget, const RenderState &inState
{
//if (fontSurface) mTiles->endTiles();
fontSurface = tile.mSurface;
mTiles->beginTiles(fontSurface,!screenGrid,bmNormal);
mTiles->beginTiles(fontSurface,!screenGrid,fontSurface->Format()==pfRGB ? bmComponentAlpha : bmNormal);
}

UserPoint p(pos.x+tile.mOx*fontToLocal,pos.y+tile.mOy*fontToLocal);
Expand Down Expand Up @@ -2139,6 +2139,7 @@ void TextField::Layout(const Matrix &inMatrix, const RenderTarget *inTarget)
for(int i=0;i<mCharGroups.size();i++)
mCharGroups[i]->UpdateFont(fontScale,!embedFonts,fontAaType);

mTilesDirty = true;
if (charPositionDirty)
{
mLinesDirty = true;
Expand Down
Loading

0 comments on commit c74fec0

Please sign in to comment.