#ifndef LIME_FONT_H #define LIME_FONT_H #include #include #include #include #include #include #include #include namespace lime { struct TextLineMetrics { float ascent; float descent; float height; float leading; float width; float x; }; enum { ffItalic = 0x01, ffBold = 0x02, }; enum AntiAliasType { aaAdvanced, aaNormal }; enum AutoSizeMode { asCenter, asLeft, asNone, asRight }; enum TextFormatAlign { tfaCenter, tfaJustify, tfaLeft, tfaRight}; enum GridFitType { gftNone, gftPixel, gftSubPixel }; template class Optional { public: Optional(const Optional &inRHS) : mVal(inRHS.mVal), mSet(inRHS.mSet) { } void operator = (const Optional &inRHS) { mVal = inRHS.mVal; mSet = inRHS.mSet; } Optional(const T&inVal) : mVal(inVal), mSet(false) { } T& operator >>(T &outRHS) { if (mSet) outRHS = mVal; return mVal; } T& operator=(const T&inRHS) { mVal = inRHS; mSet = true; return mVal; } operator T() const { return mVal; } T operator()(T inDefault) const { return mSet ? mVal : inDefault; } T &Set() { mSet=true; return mVal; } const T &Get() const { return mVal; } void Apply(Optional &inRHS) const { if (mSet) inRHS=mVal; } void IfEquals(Optional &inRHS) { if (mSet && inRHS.mSet && inRHS.mVal != mVal) mSet = false; } bool IsSet() const { return mSet; } T &__Get() { return mVal; } private: bool mSet; T mVal; }; class TextFormat : public Object { public: TextFormat(const TextFormat &,bool inInitRef=true); static TextFormat *Create(bool inInitRef = true); static TextFormat *Default(); TextFormat *IncRef() { Object::IncRef(); return this; } TextFormat *COW(); Optional align; Optional blockIndent; Optional bold; Optional bullet; Optional color; Optional font; Optional indent; Optional italic; Optional kerning; Optional leading; Optional leftMargin; Optional letterSpacing; Optional rightMargin; Optional size; Optional >tabStops; Optional target; Optional underline; Optional url; TextFormat(); ~TextFormat(); private: void operator = (const TextFormat &); }; struct CharGroup { CharGroup() : mChar0(0), mFontHeight(0), mFormat(0), mFont(0) { }; ~CharGroup(); void Clear(); bool UpdateFont(double inScale,GlyphRotation inRotation,bool inNative); void UpdateMetrics(TextLineMetrics &ioMetrics); int Height(); int Chars() { return mString.size(); } void ApplyFormat(TextFormat *inFormat); int mChar0; QuickVec mString; int mFontHeight; TextFormat *mFormat; class Font *mFont; }; typedef QuickVec CharGroups; struct Line { Line() { Clear(); } void Clear() { memset(this,0,sizeof(*this)); } TextLineMetrics mMetrics; int mY0; int mChar0; int mChars; int mCharGroup0; int mCharInGroup0; }; typedef QuickVec Lines; class FontFace { public: virtual ~FontFace() { }; static FontFace *CreateNative(const TextFormat &inFormat,double inScale); static FontFace *CreateFreeType(const TextFormat &inFormat,double inScale,AutoGCRoot *inBytes); static FontFace *CreateCFFIFont(const TextFormat &inFormat,double inScale); virtual bool GetGlyphInfo(int inChar, int &outW, int &outH, int &outAdvance, int &outOx, int &outOy) = 0; virtual void RenderGlyph(int inChar,const RenderTarget &outTarget)=0; virtual void UpdateMetrics(TextLineMetrics &ioMetrics)=0; virtual int Height()=0; virtual bool IsNative() { return false; } virtual bool WantRGB() { return false; } }; class Font : public Object { struct Glyph { Glyph() : sheet(-1), tile(-1) { } int sheet; int tile; int advance; }; public: static Font *Create(TextFormat &inFormat,double inScale,GlyphRotation inRot, bool inNative,bool inInitRef=true); Font *IncRef() { Object::IncRef(); return this; } Tile GetGlyph(int inCharacter,int &outAdvance6); void UpdateMetrics(TextLineMetrics &ioMetrics); bool IsNative() { return mFace && mFace->IsNative(); } GlyphRotation Rotation() { return mRotation; } int Height(); private: Font(FontFace *inFace, int inPixelHeight, GlyphRotation inRotation,bool inInitRef); ~Font(); Glyph mGlyph[128]; std::map mExtendedGlyph; QuickVec mSheets; FontFace *mFace; int mPixelHeight; int mCurrentSheet; GlyphRotation mRotation; }; class FontCache { }; } // end namespace lime #endif