Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
128 changes: 59 additions & 69 deletions src/SexyAppFramework/SysFont.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@
#include "SDL3Renderer/SDL3Renderer.h"
#endif


using namespace Sexy;

static std::string ResolveFontFile(const std::string &theFace)
Expand Down Expand Up @@ -56,7 +55,7 @@ static std::string ResolveFontFile(const std::string &theFace)
continue;
std::string aStemLower = aStem;
std::transform(aStemLower.begin(), aStemLower.end(), aStemLower.begin(),
[](unsigned char c) { return std::tolower(c); });
[](unsigned char c) { return std::tolower(c); });
if (aStemLower == aLower)
return anEntry.path().string();
}
Expand All @@ -72,29 +71,28 @@ static std::string ResolveFontFile(const std::string &theFace)
return "";
}


SysFont::SysFont(const std::string &theFace, int thePointSize, bool bold, bool italics, bool underline)
{
Init(gSexyAppBase, theFace, thePointSize, bold, italics, underline, false);
}

SysFont::SysFont(SexyAppBase *theApp,
const std::string &theFace,
int thePointSize,
bool bold,
bool italics,
bool underline)
const std::string &theFace,
int thePointSize,
bool bold,
bool italics,
bool underline)
{
Init(theApp, theFace, thePointSize, bold, italics, underline, true);
}

void SysFont::Init(SexyAppBase *theApp,
const std::string &theFace,
int thePointSize,
bool bold,
bool italics,
bool underline,
bool useDevCaps)
const std::string &theFace,
int thePointSize,
bool bold,
bool italics,
bool underline,
bool useDevCaps)
{
mApp = theApp;
mApp->mRenderer->mSysFonts.insert(this);
Expand Down Expand Up @@ -127,11 +125,11 @@ void SysFont::Init(SexyAppBase *theApp,
FT_Select_Charmap(aFontFace, FT_ENCODING_UNICODE);
if (mItalic)
{
FT_Matrix matrix = {1 << 16, (FT_Fixed)(0.3 * (1 << 16)), 0, 1 << 16};
FT_Matrix matrix = { 1 << 16, (FT_Fixed)(0.3 * (1 << 16)), 0, 1 << 16 };
FT_Set_Transform(aFontFace, &matrix, nullptr);
}

mFontData = new TrueTypeData(this, aFontFace, thePointSize);
mFontData = std::make_shared<TrueTypeData>(mApp, aFontFace, thePointSize, mBold);

if (aFontFace->size)
{
Expand Down Expand Up @@ -170,9 +168,7 @@ void SysFont::Reinit()
aFontFace->style_flags = aPrevFlags;

int aOldSize = mFontData->mSize;
delete mFontData;
mFontData = nullptr;
mFontData = new TrueTypeData(this, aFontFace, aOldSize);
mFontData = std::make_shared<TrueTypeData>(mApp, aFontFace, aOldSize, mBold);

if (aFontFace->size)
{
Expand All @@ -187,7 +183,6 @@ SysFont::SysFont(const SysFont &theSysFont)
mHeight = theSysFont.mHeight;
mAscent = theSysFont.mAscent;
mFontData = theSysFont.mFontData;
mFontData->mFont = this;
mBold = theSysFont.mBold;
mItalic = theSysFont.mItalic;

Expand All @@ -196,20 +191,18 @@ SysFont::SysFont(const SysFont &theSysFont)

SysFont::~SysFont()
{
if (mFontData)
delete mFontData;
mApp->mRenderer->mSysFonts.erase(this);
}

ImageFont *SysFont::CreateImageFont()
{
{
//todo: uuhhh implement?
return nullptr;
}

int SysFont::StringWidth(const SexyString &theString)
{
int aWidth = 0;
{
int aWidth = 0;
auto it = theString.begin();
auto end = theString.end();
while (it != end)
Expand All @@ -222,14 +215,14 @@ int SysFont::StringWidth(const SexyString &theString)
}

void SysFont::DrawString(
Graphics *g, int theX, int theY, const SexyString &theString, const Color &theColor, const Rect &theClipRect)
{
Graphics *g, int theX, int theY, const SexyString &theString, const Color &theColor, const Rect &theClipRect)
{
if (mFontData == nullptr)
return;
int posX = theX;
int posY = theY;
int underlineY = posY - ((mFontData->mFace->underline_position * mFontData->mFace->size->metrics.y_scale) >> 16 >> 6);

auto it = theString.begin();
auto end = theString.end();
while (it != end)
Expand All @@ -245,53 +238,51 @@ void SysFont::DrawString(
{
Color aShadowColor = Color(0, 0, 0, 0);
g->mDestImage->BltRawTexture(
mFontData->mAtlas.mAtlas,
aGlyph.mWidth,
aGlyph.mHeight,
Rect(aDrawX + g->mTransX + 1, aDrawY - mAscent + 1 + g->mTransY, aGlyph.mWidth, aGlyph.mHeight),
Rect(aGlyph.mX, aGlyph.mY, aGlyph.mWidth, aGlyph.mHeight),
theClipRect,
aShadowColor,
0);
mFontData->mAtlas.mAtlas,
aGlyph.mWidth,
aGlyph.mHeight,
Rect(aDrawX + g->mTransX + 1, aDrawY - mAscent + 1 + g->mTransY, aGlyph.mWidth, aGlyph.mHeight),
Rect(aGlyph.mX, aGlyph.mY, aGlyph.mWidth, aGlyph.mHeight),
theClipRect,
aShadowColor,
0);
}

g->mDestImage->BltRawTexture(
mFontData->mAtlas.mAtlas,
mFontData->mAtlas.mWidth,
mFontData->mAtlas.mHeight,
Rect(aDrawX, aDrawY, aGlyph.mWidth, aGlyph.mHeight),
Rect(aGlyph.mX, aGlyph.mY, aGlyph.mWidth, aGlyph.mHeight),
theClipRect,
theColor,
0);

mFontData->mAtlas.mAtlas,
mFontData->mAtlas.mWidth,
mFontData->mAtlas.mHeight,
Rect(aDrawX, aDrawY, aGlyph.mWidth, aGlyph.mHeight),
Rect(aGlyph.mX, aGlyph.mY, aGlyph.mWidth, aGlyph.mHeight),
theClipRect,
theColor,
0);
}
else
{
if (mDrawShadow)
{
Color aShadowColor = Color(0, 0, 0, 0);
mApp->mRenderer->BltRawTexture(
mFontData->mAtlas.mAtlas,
mFontData->mAtlas.mWidth,
mFontData->mAtlas.mHeight,
Rect(aDrawX + g->mTransX + 1, aDrawY - mAscent + 1 + g->mTransY, aGlyph.mWidth, aGlyph.mHeight),
Rect(aGlyph.mX, aGlyph.mY, aGlyph.mWidth, aGlyph.mHeight),
theClipRect,
aShadowColor,
0);

mFontData->mAtlas.mAtlas,
mFontData->mAtlas.mWidth,
mFontData->mAtlas.mHeight,
Rect(aDrawX + g->mTransX + 1, aDrawY - mAscent + 1 + g->mTransY, aGlyph.mWidth, aGlyph.mHeight),
Rect(aGlyph.mX, aGlyph.mY, aGlyph.mWidth, aGlyph.mHeight),
theClipRect,
aShadowColor,
0);
}

mApp->mRenderer->BltRawTexture(
mFontData->mAtlas.mAtlas,
mFontData->mAtlas.mWidth,
mFontData->mAtlas.mHeight,
Rect(aDrawX + g->mTransX + 1, aDrawY - mAscent + 1 + g->mTransY, aGlyph.mWidth, aGlyph.mHeight),
Rect(aGlyph.mX, aGlyph.mY, aGlyph.mWidth, aGlyph.mHeight),
theClipRect,
theColor,
0);
mFontData->mAtlas.mAtlas,
mFontData->mAtlas.mWidth,
mFontData->mAtlas.mHeight,
Rect(aDrawX + g->mTransX + 1, aDrawY - mAscent + 1 + g->mTransY, aGlyph.mWidth, aGlyph.mHeight),
Rect(aGlyph.mX, aGlyph.mY, aGlyph.mWidth, aGlyph.mHeight),
theClipRect,
theColor,
0);
}

posX += aGlyph.mAdvance;
Expand All @@ -305,8 +296,7 @@ void SysFont::DrawString(
{
if (mUnderlined)
mApp->mRenderer->DrawLine(
theX + g->mTransX + 1, underlineY, StringWidth(theString), underlineY, theColor, 0);

theX + g->mTransX + 1, underlineY, StringWidth(theString), underlineY, theColor, 0);
}
}

Expand All @@ -324,7 +314,7 @@ void TrueTypeData::Init()
FT_Set_Pixel_Sizes(mFace, 0, mSize);
if (mAtlas.mAtlas != nullptr)
{
mFont->mApp->mRenderer->DeleteTexture(mAtlas.mAtlas);
mApp->mRenderer->DeleteTexture(mAtlas.mAtlas);
}
mAtlas.mGlyphs.clear();

Expand All @@ -342,8 +332,8 @@ void TrueTypeData::Init()
{
GlpyhAtlasEntry aGlyph;
FT_Load_Char(mFace, aSetupChar, FT_LOAD_RENDER);
if (mFont->mBold)

if (mBold)
{
FT_GlyphSlot_Embolden(mFace->glyph);
}
Expand Down Expand Up @@ -388,7 +378,7 @@ void TrueTypeData::Init()

mAtlas.mGlyphs[aSetupChar] = aGlyph;
}
mAtlas.mAtlas = mFont->mApp->mRenderer->CreateTexture(anAtlasPixels, mAtlas.mWidth, mAtlas.mHeight, RawPixelFormat::RAW_FORMAT_RGBA, 1);
mAtlas.mAtlas = mApp->mRenderer->CreateTexture(anAtlasPixels, mAtlas.mWidth, mAtlas.mHeight, RawPixelFormat::RAW_FORMAT_RGBA, 1);

delete[] anAtlasPixels;
}
Expand All @@ -397,7 +387,7 @@ TrueTypeData::~TrueTypeData()
{
if (mAtlas.mAtlas != nullptr)
{
mFont->mApp->mRenderer->DeleteTexture(mAtlas.mAtlas);
mApp->mRenderer->DeleteTexture(mAtlas.mAtlas);
}
mAtlas.mGlyphs.clear();
FT_Done_Face(mFace);
Expand Down
70 changes: 34 additions & 36 deletions src/SexyAppFramework/SysFont.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include "Font.h"
#include <unordered_map>
#include <freetype/freetype.h>
#include <memory>

namespace Sexy
{
Expand All @@ -30,71 +31,68 @@ struct GlyphAtlas
std::unordered_map<uint32_t, GlpyhAtlasEntry> mGlyphs;
};

class TrueTypeData
{
public:
GlyphAtlas mAtlas;
SexyAppBase *mApp;
FT_Face mFace;
int mSize;
bool mBold;
bool mIsDirty;

class TrueTypeData;
TrueTypeData(SexyAppBase *theApp, FT_Face theFace, int theSize, bool theBold) : mApp(theApp), mFace(theFace), mSize(theSize), mBold(theBold)
{
Init();
}

~TrueTypeData();

void Init();
};

class SysFont : public Font
{
public:
TrueTypeData* mFontData;
std::shared_ptr<TrueTypeData> mFontData;
SexyAppBase *mApp;
std::string mFontName;
bool mDrawShadow;
bool mBold;
bool mItalic;
bool mUnderlined;


void Init(SexyAppBase *theApp,
const std::string &theFace,
int thePointSize,
bool bold,
bool italics,
bool underline,
bool useDevCaps);
const std::string &theFace,
int thePointSize,
bool bold,
bool italics,
bool underline,
bool useDevCaps);

void Reinit();

public:
SysFont(
const std::string &theFace, int thePointSize, bool bold = false, bool italics = false, bool underline = false);
const std::string &theFace, int thePointSize, bool bold = false, bool italics = false, bool underline = false);
SysFont(SexyAppBase *theApp,
const std::string &theFace,
int thePointSize,
bool bold = false,
bool italics = false,
bool underline = false);
const std::string &theFace,
int thePointSize,
bool bold = false,
bool italics = false,
bool underline = false);
SysFont(const SysFont &theSysFont);

virtual ~SysFont();

ImageFont *CreateImageFont();
virtual int StringWidth(const SexyString &theString);
virtual void DrawString(
Graphics *g, int theX, int theY, const SexyString &theString, const Color &theColor, const Rect &theClipRect);
Graphics *g, int theX, int theY, const SexyString &theString, const Color &theColor, const Rect &theClipRect);

virtual Font *Duplicate();

};

struct TrueTypeData
{
GlyphAtlas mAtlas;
SysFont *mFont;
FT_Face mFace;
int mSize;
bool mIsDirty;

TrueTypeData(SysFont *theFontPtr, FT_Face &theFace, int theSize) : mFont(theFontPtr), mFace(theFace), mSize(theSize)
{
Init();
}

~TrueTypeData();

void Init();
};

} // namespace Sexy

#endif //__SYSFONT_H__
#endif //__SYSFONT_H__
Loading