Skip to content

Commit

Permalink
Clean Up #3 (#25)
Browse files Browse the repository at this point in the history
* refactor textdirection.

* clean up some weirdness.

* add render viewport

* move some more function out of the font class.

* rearranging around fonts
  • Loading branch information
wutipong authored Jan 22, 2024
1 parent 7c3f32a commit 7324909
Show file tree
Hide file tree
Showing 9 changed files with 236 additions and 233 deletions.
26 changes: 26 additions & 0 deletions colors.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#define COLORS_HPP

#include <SDL2/SDL.h>
#include <imgui.h>

constexpr SDL_Color debugGlyphBoundColor{0xFF, 0xFF, 0x80, 0xFF};
constexpr SDL_Color debugBaselineColor{0xFF, 0x00, 0x00, 0xFF};
Expand All @@ -10,4 +11,29 @@ constexpr SDL_Color debugAscendColor{0x40, 0x40, 0xFF, 0x80};
constexpr SDL_Color debugDescendColor{0x40, 0xFF, 0x40, 0x80};
constexpr SDL_Color backgroundColor{0x80, 0x80, 0x80, 0xFF};

constexpr ImVec4 SDLColorToImVec4(const SDL_Color &color) {
ImVec4 output{
static_cast<float>(color.r) / 255.0f,
static_cast<float>(color.g) / 255.0f,
static_cast<float>(color.b) / 255.0f,
static_cast<float>(color.a) / 255.0f,
};

return output;
}

constexpr auto f4DebugGlyphBoundColor = SDLColorToImVec4(debugGlyphBoundColor);
constexpr auto f4DebugAscendColor = SDLColorToImVec4(debugAscendColor);
constexpr auto f4DebugDescendColor = SDLColorToImVec4(debugDescendColor);
constexpr auto f4DebugBaselineColor = SDLColorToImVec4(debugBaselineColor);
constexpr auto f4DebugCaretColor = SDLColorToImVec4(debugCaretColor);

constexpr SDL_Color Float4ToSDLColor(const float& r, const float& g, const float &b, const float &a = 1.0f ){
return {
static_cast<uint8_t>(r * 255.0f),
static_cast<uint8_t>(g * 255.0f),
static_cast<uint8_t>(b * 255.0f),
static_cast<uint8_t>(a * 255.0f),
};
}
#endif
6 changes: 3 additions & 3 deletions context.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,13 @@ void LoadContext(Context &ctx, const std::filesystem::path &path) {

json js;

// If there's something wrong with reading file, log an error and return.
// If there's something wrong with reading file, log an error and return.
try {
std::string str;
str = LoadFile<std::string>(path);

js = json::parse(str);
} catch (const json::exception& e) {
} catch (const json::exception &e) {
spdlog::error("Error reading context file: {}", e.what());
return;
}
Expand All @@ -47,7 +47,7 @@ void LoadContext(Context &ctx, const std::filesystem::path &path) {
c.windowBound.w = js["window_bound"]["width"];
c.windowBound.h = js["window_bound"]["height"];
c.fontPath = js["font_path"];
} catch (const json::exception& e) {
} catch (const json::exception &e) {
spdlog::error("Error reading context file value: {}", e.what());
}

Expand Down
116 changes: 43 additions & 73 deletions font.cpp
Original file line number Diff line number Diff line change
@@ -1,18 +1,16 @@
#include "font.hpp"

#include <harfbuzz/hb-ft.h>
#include <magic_enum_all.hpp>
#include <spdlog/spdlog.h>
#include <utf8cpp/utf8.h>

#include "io_util.hpp"
#include "text_renderer.hpp"
#include "texture.hpp"

#include FT_SFNT_NAMES_H
#include FT_BITMAP_H
#include FT_MULTIPLE_MASTERS_H

#include <harfbuzz/hb-ft.h>
#include <magic_enum_all.hpp>
#include <spdlog/spdlog.h>
#include "io_util.hpp"
#include "text_renderer.hpp"
#include "texture.hpp"

namespace {

Expand Down Expand Up @@ -41,7 +39,7 @@ bool Font::Init() {

void Font::CleanUp() { FT_Done_FreeType(library); }

Font::Font() : textRenderer(TextRenderNoShape){};
Font::Font(){};

Font &Font::operator=(const Font &f) {
data = f.data;
Expand All @@ -53,12 +51,12 @@ Font &Font::operator=(const Font &f) {
Font::Font(const Font &f) : data(f.data) { Initialize(); }

Font::~Font() {
hb_font_destroy(hb_font);
hb_font = nullptr;
hb_font_destroy(hbFont);
hbFont = nullptr;

Invalidate();

FT_Done_Face(face);
FT_Done_Face(ftFace);
}

bool Font::LoadFile(const std::string &path) {
Expand Down Expand Up @@ -87,28 +85,26 @@ static std::string ConvertFromFontString(const char *str, const int &length) {
bool Font::Initialize() {
family = "";
subFamily = "";
textRenderer = TextRenderNoShape;
textRendererEnum = TextRenderEnum::NoShape;

auto error = FT_New_Memory_Face(
library, reinterpret_cast<const FT_Byte *>(data.data()), data.size(), 0,
&face);
&ftFace);

if (error) {
data.clear();
return false;
}

hb_font = hb_ft_font_create_referenced(face);
hbFont = hb_ft_font_create_referenced(ftFace);

Invalidate();
fontSize = -1;

family = face->family_name;
subFamily = face->style_name;
family = ftFace->family_name;
subFamily = ftFace->style_name;

if (IsVariableFont()) {
auto hb_face = hb_font_get_face(hb_font);
auto hb_face = hb_font_get_face(hbFont);
auto count = hb_ot_var_get_axis_count(hb_face);

std::vector<hb_ot_var_axis_info_t> hbAxisInfo;
Expand Down Expand Up @@ -154,45 +150,45 @@ void Font::SetFontSize(const int &size) {
fontSize = size;
Invalidate();

auto error = FT_Set_Pixel_Sizes(face, 0, size);
hb_ft_font_changed(hb_font);
auto error = FT_Set_Pixel_Sizes(ftFace, 0, size);
hb_ft_font_changed(hbFont);

ascend = FTPosToFloat(face->size->metrics.ascender);
descend = FTPosToFloat(face->size->metrics.descender);
height = FTPosToFloat(face->size->metrics.height);
ascend = FTPosToFloat(ftFace->size->metrics.ascender);
descend = FTPosToFloat(ftFace->size->metrics.descender);
height = FTPosToFloat(ftFace->size->metrics.height);
linegap = height + descend - ascend;
}

Glyph Font::CreateGlyph(SDL_Renderer *renderer, const int &index) {
int bearing = 0;
int advance;

FT_Load_Glyph(face, index, FT_LOAD_RENDER);
FT_Load_Glyph(ftFace, index, FT_LOAD_RENDER);

advance = static_cast<int>(FTPosToFloat(face->glyph->advance.x));

auto width = face->glyph->bitmap.width;
auto height = face->glyph->bitmap.rows;
const auto advance = static_cast<int>(FTPosToFloat(ftFace->glyph->advance.x));
const auto width = ftFace->glyph->bitmap.width;
const auto height = ftFace->glyph->bitmap.rows;

FT_Bitmap bitmap;
FT_Bitmap_Init(&bitmap);
FT_Bitmap_Convert(library, &face->glyph->bitmap, &bitmap, 1);
FT_Bitmap_Convert(library, &ftFace->glyph->bitmap, &bitmap, 1);

auto texture = LoadTextureFromBitmap(renderer, bitmap);

FT_Bitmap_Done(library, &bitmap);

auto x = face->glyph->bitmap_left;
auto y = face->glyph->bitmap_top - height;
const auto x = static_cast<int>(ftFace->glyph->bitmap_left);
const auto y = static_cast<int>(ftFace->glyph->bitmap_top - height);

SDL_Rect bound{x, static_cast<int>(y), static_cast<int>(width),
static_cast<int>(height)};
SDL_Rect bound{
x,
y,
static_cast<int>(width),
static_cast<int>(height),
};

return {texture, bound, advance, bearing};
return {texture, bound, advance};
}

Glyph Font::CreateGlyphFromChar(SDL_Renderer *renderer, const char16_t &ch) {
auto index = FT_Get_Char_Index(face, ch);
auto index = FT_Get_Char_Index(ftFace, ch);

return CreateGlyph(renderer, index);
}
Expand All @@ -210,43 +206,17 @@ Glyph &Font::GetGlyph(SDL_Renderer *renderer, const int &index) {
}

Glyph &Font::GetGlyphFromChar(SDL_Renderer *renderer, const char16_t &ch) {
const auto index = FT_Get_Char_Index(face, ch);
const auto index = FT_Get_Char_Index(ftFace, ch);

return Font::GetGlyph(renderer, index);
}

void Font::SetTextRenderer(const TextRenderEnum &t) {
textRendererEnum = t;
switch (textRendererEnum) {
case TextRenderEnum::NoShape:
textRenderer = TextRenderNoShape;
break;
case TextRenderEnum::LeftToRight:
textRenderer = TextRenderLeftToRight;
break;
case TextRenderEnum::RightToLeft:
textRenderer = TextRenderRightToLeft;
break;
case TextRenderEnum::TopToBottom:
textRenderer = TextRenderTopToBottom;
break;
}
}

void Font::RenderText(SDL_Renderer *renderer, Context &ctx,
const std::string &str, const SDL_Color &color,
const std::string &language, const hb_script_t &script) {
if (!IsValid())
return;

textRenderer(renderer, ctx, *this, str, color, language, script);
}

bool Font::IsVariableFont() const {
if (!hb_font)
if (!IsValid())
return false;

auto hb_face = hb_font_get_face(hb_font);
auto hb_face = hb_font_get_face(hbFont);

return hb_ot_var_has_data(hb_face);
}

Expand All @@ -269,7 +239,7 @@ void Font::SetVariationValues(
std::vector<hb_variation_t> variations;

FT_MM_Var *amaster;
FT_Get_MM_Var(face, &amaster);
FT_Get_MM_Var(ftFace, &amaster);

magic_enum::enum_for_each<VariationAxis>(
[&limits, &variations, &values](const VariationAxis &axis) {
Expand All @@ -281,7 +251,7 @@ void Font::SetVariationValues(
}
});

hb_font_set_variations(hb_font, variations.data(), variations.size());
hb_font_set_variations(hbFont, variations.data(), variations.size());

std::vector<FT_Fixed> coords;
for (int i = 0; i < amaster->num_axis; i++) {
Expand All @@ -302,9 +272,9 @@ void Font::SetVariationValues(
}
}

FT_Set_Var_Design_Coordinates(face, coords.size(), coords.data());
FT_Set_Var_Design_Coordinates(ftFace, coords.size(), coords.data());
FT_Done_MM_Var(library, amaster);
hb_ft_font_changed(hb_font);
hb_ft_font_changed(hbFont);

Invalidate();
}
42 changes: 10 additions & 32 deletions font.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,32 +15,18 @@
#include <string>
#include <vector>

enum class TextRenderEnum {
NoShape,
LeftToRight,
RightToLeft,
TopToBottom,
};

class Font;

typedef std::function<void(SDL_Renderer *renderer, Context &ctx, Font &font,
const std::string &str, const SDL_Color &color,
const std::string &language,
const hb_script_t &script)>
TextRenderFunction;

struct Glyph {
SDL_Texture *texture;
SDL_Rect bound;
int advance;
int bearing;
SDL_Texture *texture{nullptr};
SDL_Rect bound{};
int advance = 0;
};

inline float FTPosToFloat(const FT_Pos &value) {
constexpr inline float FTPosToFloat(const FT_Pos &value) {
return static_cast<float>(value) / 64.0f;
}
inline float HBPosToFloat(const hb_position_t &value) {
constexpr inline float HBPosToFloat(const hb_position_t &value) {
return static_cast<float>(value) / 64.0f;
}

Expand Down Expand Up @@ -79,7 +65,8 @@ class Font {

std::string GetFamilyName() const { return family; }
std::string GetSubFamilyName() const { return subFamily; }
bool IsValid() const { return face != nullptr; }

bool IsValid() const { return ftFace != nullptr; }

bool IsVariableFont() const;

Expand All @@ -91,13 +78,7 @@ class Font {
float LineGap() const { return linegap; }
float LineHeight() const { return height; }

hb_font_t *HbFont() const { return hb_font; }

void SetTextRenderer(const TextRenderEnum &t);

void RenderText(SDL_Renderer *renderer, Context &ctx, const std::string &str,
const SDL_Color &color, const std::string &language,
const hb_script_t &script);
hb_font_t *HbFont() const { return hbFont; }

magic_enum::containers::array<VariationAxis, std::optional<AxisInfo>>
GetAxisInfos() const;
Expand All @@ -114,10 +95,10 @@ class Font {
Glyph CreateGlyphFromChar(SDL_Renderer *renderer, const char16_t &ch);

std::vector<char> data{};
FT_Face face{};
FT_Face ftFace{};
hb_font_t *hbFont{nullptr};

int fontSize{-1};
hb_font_t *hb_font{nullptr};

std::map<unsigned int, Glyph> glyphMap;

Expand All @@ -129,9 +110,6 @@ class Font {
std::string family;
std::string subFamily;

TextRenderFunction textRenderer;
TextRenderEnum textRendererEnum{TextRenderEnum::NoShape};

magic_enum::containers::array<VariationAxis, std::optional<AxisInfo>>
axisInfo{};
};
1 change: 1 addition & 0 deletions main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ int main(int argc, char **argv) {
if (event.type == SDL_QUIT)
break;
}
ctx.windowBound = {0};
SDL_GetWindowSize(window, &ctx.windowBound.w, &ctx.windowBound.h);

ImGui_ImplSDL2_NewFrame(window);
Expand Down
Loading

0 comments on commit 7324909

Please sign in to comment.