128 lines
3.3 KiB
C
128 lines
3.3 KiB
C
|
/*
|
||
|
Copyright (c) 2013 yvt
|
||
|
|
||
|
This file is part of OpenSpades.
|
||
|
|
||
|
OpenSpades is free software: you can redistribute it and/or modify
|
||
|
it under the terms of the GNU General Public License as published by
|
||
|
the Free Software Foundation, either version 3 of the License, or
|
||
|
(at your option) any later version.
|
||
|
|
||
|
OpenSpades is distributed in the hope that it will be useful,
|
||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
|
GNU General Public License for more details.
|
||
|
|
||
|
You should have received a copy of the GNU General Public License
|
||
|
along with OpenSpades. If not, see <http://www.gnu.org/licenses/>.
|
||
|
|
||
|
*/
|
||
|
|
||
|
#include <list>
|
||
|
#include <unordered_map>
|
||
|
|
||
|
#include <Client/IFont.h>
|
||
|
#include <Core/TMPUtils.h>
|
||
|
|
||
|
struct FT_FaceRec_;
|
||
|
typedef struct FT_FaceRec_ *FT_Face;
|
||
|
|
||
|
namespace spades {
|
||
|
class Bitmap;
|
||
|
}
|
||
|
|
||
|
namespace spades {
|
||
|
namespace client {
|
||
|
class IImage;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
namespace spades {
|
||
|
namespace ngclient {
|
||
|
struct FTFaceWrapper;
|
||
|
class FTFont;
|
||
|
|
||
|
class FTFontSet : public RefCountedObject {
|
||
|
friend class FTFont;
|
||
|
std::list<std::unique_ptr<FTFaceWrapper>> faces;
|
||
|
|
||
|
protected:
|
||
|
~FTFontSet();
|
||
|
|
||
|
public:
|
||
|
FTFontSet();
|
||
|
void AddFace(const std::string &fileName);
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* FreeType2 based font renderer.
|
||
|
*
|
||
|
|
||
|
* Warning: only one thread can access multiple FTFonts sharing the same FTFontSet
|
||
|
* at the same time.
|
||
|
*/
|
||
|
class FTFont : public client::IFont {
|
||
|
Handle<client::IRenderer> renderer;
|
||
|
|
||
|
struct GlyphImage {
|
||
|
client::IImage &img;
|
||
|
AABB2 const bounds;
|
||
|
Vector2 const offset;
|
||
|
GlyphImage(client::IImage &img, const AABB2 &bounds, const Vector2 &offset)
|
||
|
: img(img), bounds(bounds), offset(offset) {}
|
||
|
};
|
||
|
struct Glyph {
|
||
|
FT_Face face;
|
||
|
uint32_t charIndex;
|
||
|
Vector2 advance;
|
||
|
stmp::optional<GlyphImage> image;
|
||
|
stmp::optional<GlyphImage> blurImage;
|
||
|
Handle<Bitmap> bmp;
|
||
|
};
|
||
|
struct GlyphHash {
|
||
|
std::size_t operator()(const std::pair<FT_Face, uint32_t> &p) const {
|
||
|
return std::hash<FT_Face>()(p.first) ^ std::hash<uint32_t>()(p.second);
|
||
|
}
|
||
|
};
|
||
|
std::unordered_map<std::pair<FT_Face, uint32_t>, Glyph, GlyphHash> glyphs;
|
||
|
std::unordered_map<uint32_t, std::reference_wrapper<Glyph>> glyphMap;
|
||
|
float lineHeight;
|
||
|
/** em height */
|
||
|
float height;
|
||
|
float baselineY;
|
||
|
|
||
|
bool rendererIsLowQuality;
|
||
|
|
||
|
Handle<FTFontSet> fontSet;
|
||
|
|
||
|
struct Bin;
|
||
|
std::list<Bin> bins;
|
||
|
int binSize;
|
||
|
|
||
|
Glyph *GetGlyph(uint32_t code);
|
||
|
template <class T, class T2, class T3>
|
||
|
void SplitTextIntoGlyphs(const std::string &, T glyphHandler, T3 fallbackHandler,
|
||
|
T2 lineBreakHandler);
|
||
|
|
||
|
void RenderGlyph(Glyph &);
|
||
|
void RenderBlurGlyph(Glyph &);
|
||
|
|
||
|
protected:
|
||
|
~FTFont();
|
||
|
|
||
|
public:
|
||
|
FTFont(client::IRenderer *, FTFontSet *, float height, float lineHeight);
|
||
|
|
||
|
Vector2 Measure(const std::string &) override;
|
||
|
|
||
|
float GetHeight() const { return height; }
|
||
|
float GetLineHeight() const { return lineHeight; }
|
||
|
|
||
|
void Draw(const std::string &, Vector2 offset, float scale, Vector4 color) override;
|
||
|
void DrawBlurred(const std::string &, Vector2 offset, float scale, Vector4 color);
|
||
|
void DrawShadow(const std::string &, const Vector2 &offset, float scale,
|
||
|
const Vector4 &color, const Vector4 &shadowColor) override;
|
||
|
};
|
||
|
}
|
||
|
}
|