Files
lime/project/include/Font.h
2013-11-25 23:32:25 -08:00

211 lines
4.8 KiB
C++

#ifndef NME_FONT_H
#define NME_FONT_H
#include <Object.h>
#include <Utils.h>
#include <Graphics.h>
#include <Tilesheet.h>
#include <map>
#include <string>
#include <Geom.h>
#include <ByteArray.h>
namespace nme
{
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<typename T>
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<T> &inRHS) const { if (mSet) inRHS=mVal; }
void IfEquals(Optional<T> &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<TextFormatAlign> align;
Optional<int> blockIndent;
Optional<bool> bold;
Optional<bool> bullet;
Optional<uint32> color;
Optional<WString> font;
Optional<int> indent;
Optional<bool> italic;
Optional<bool> kerning;
Optional<int> leading;
Optional<int> leftMargin;
Optional<int> letterSpacing;
Optional<int> rightMargin;
Optional<int> size;
Optional<QuickVec<int> >tabStops;
Optional<WString> target;
Optional<bool> underline;
Optional<WString> 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<wchar_t,0> mString;
int mFontHeight;
TextFormat *mFormat;
class Font *mFont;
};
typedef QuickVec<CharGroup *> 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<Line> 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<int,Glyph> mExtendedGlyph;
QuickVec<Tilesheet *> mSheets;
FontFace *mFace;
int mPixelHeight;
int mCurrentSheet;
GlyphRotation mRotation;
};
class FontCache
{
};
} // end namespace nme
#endif