Skip to content

Commit

Permalink
try calling freetype
Browse files Browse the repository at this point in the history
  • Loading branch information
mikerreed committed Mar 12, 2022
1 parent 3f104f0 commit 0f2cc50
Show file tree
Hide file tree
Showing 3 changed files with 240 additions and 6 deletions.
15 changes: 11 additions & 4 deletions skia/viewer/build/premake5.lua
Original file line number Diff line number Diff line change
Expand Up @@ -19,17 +19,24 @@ includedirs {"../include", "../../../include", "../../renderer/include", "../../
"../../dependencies/skia", "../../dependencies/skia/include/core",
"../../dependencies/skia/include/effects", "../../dependencies/skia/include/gpu",
"../../dependencies/skia/include/config", "../../dependencies/imgui", "../../dependencies",
"../../dependencies/gl3w/build/include"}
"../../dependencies/gl3w/build/include",
"/Users/mike/other/freetype/include"
}

links {"Cocoa.framework", "IOKit.framework", "CoreVideo.framework", "rive", "skia", "rive_skia_renderer", "glfw3"}
links {
"Cocoa.framework", "IOKit.framework", "CoreVideo.framework",
"rive", "skia", "rive_skia_renderer", "glfw3",
"freetype",
}
libdirs {"../../../build/%{cfg.system}/bin/%{cfg.buildcfg}", "../../dependencies/glfw_build/src",
"../../dependencies/skia/out/static", "../../renderer/build/%{cfg.system}/bin/%{cfg.buildcfg}"}
"../../dependencies/skia/out/static", "../../renderer/build/%{cfg.system}/bin/%{cfg.buildcfg}",}

files {"../src/**.cpp", "../../dependencies/gl3w/build/src/gl3w.c",
"../../dependencies/imgui/backends/imgui_impl_glfw.cpp",
"../../dependencies/imgui/backends/imgui_impl_opengl3.cpp", "../../dependencies/imgui/imgui_widgets.cpp",
"../../dependencies/imgui/imgui.cpp", "../../dependencies/imgui/imgui_tables.cpp",
"../../dependencies/imgui/imgui_draw.cpp"}
"../../dependencies/imgui/imgui_draw.cpp",
}

buildoptions {"-Wall", "-fno-exceptions", "-fno-rtti", "-flto=full"}
filter "configurations:debug"
Expand Down
223 changes: 223 additions & 0 deletions skia/viewer/src/fonts.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,223 @@
#include "rive/renderer.hpp"
#include "SkData.h"

#include <ft2build.h>
#include FT_FREETYPE_H

#include <freetype/ftadvanc.h>
#include <freetype/ftimage.h>
#include <freetype/ftbitmap.h>
#ifdef FT_COLOR_H // 2.10.0
# include <freetype/ftcolor.h>
#endif
#include <freetype/freetype.h>
#include <freetype/ftlcdfil.h>
#include <freetype/ftmodapi.h>
#include <freetype/ftmm.h>
#include <freetype/ftoutln.h>
#include <freetype/ftsizes.h>
#include <freetype/ftsystem.h>
#include <freetype/tttables.h>
#include <freetype/t1tables.h>
#include <freetype/ftfntfmt.h>




typedef struct FT_LibraryRec_* FT_Library;
typedef struct FT_FaceRec_* FT_Face;
typedef struct FT_StreamRec_* FT_Stream;
typedef signed long FT_Pos;
typedef struct FT_BBox_ FT_BBox;

struct PathSink {

void move(float x, float y) {
printf("move %g %g\n", x, y);
}
void line(float x, float y) {
printf("line %g %g\n", x, y);
}
void quad(float x0, float y0, float x1, float y1) {
printf("quad %g %g %g %g\n", x0, y0, x1, y1);
}
void cubic(float x0, float y0, float x1, float y1, float x2, float y2) {
printf("cube %g %g %g %g %g %g\n", x0, y0, x1, y1, x2, y2);
}
void close() {
printf("close\n");
}
};

struct FTPathSinkCaller {
private:
PathSink* m_Sink;
// we have to manually close contours
bool m_ReadyToClose = false;

static inline float dot6tofloat(int32_t x) {
return x * (1.0f/64);
}

static int Move(const FT_Vector* pt, void* ctx) {
auto caller = (FTPathSinkCaller*)ctx;
if (caller->m_ReadyToClose) {
caller->m_Sink->close();
caller->m_ReadyToClose = false;
}
caller->m_Sink->move(dot6tofloat(pt->x), -dot6tofloat(pt->y));
return 0;
}

static int Line(const FT_Vector* pt, void* ctx) {
auto caller = (FTPathSinkCaller*)ctx;
caller->m_Sink->move(dot6tofloat(pt->x), -dot6tofloat(pt->y));
caller->m_ReadyToClose = true;
return 0;
}

static int Quad(const FT_Vector* pt0, const FT_Vector* pt1, void* ctx) {
auto caller = (FTPathSinkCaller*)ctx;
caller->m_Sink->quad(dot6tofloat(pt0->x), -dot6tofloat(pt0->y),
dot6tofloat(pt1->x), -dot6tofloat(pt1->y));
caller->m_ReadyToClose = true;
return 0;
}

static int Cubic(const FT_Vector* pt0, const FT_Vector* pt1, const FT_Vector* pt2, void* ctx) {
auto caller = (FTPathSinkCaller*)ctx;
caller->m_Sink->cubic(dot6tofloat(pt0->x), -dot6tofloat(pt0->y),
dot6tofloat(pt1->x), -dot6tofloat(pt1->y),
dot6tofloat(pt2->x), -dot6tofloat(pt2->y));
caller->m_ReadyToClose = true;
return 0;
}

public:
FTPathSinkCaller(PathSink* sink) : m_Sink(sink) {}

inline static constexpr const FT_Outline_Funcs Funcs{
FTPathSinkCaller::Move,
FTPathSinkCaller::Line,
FTPathSinkCaller::Quad,
FTPathSinkCaller::Cubic,
0, // shift
0, // delta
};
};

struct FTLib {
FT_Library m_Lib;

FTLib() : m_Lib(nullptr) {
int err = FT_Init_FreeType(&m_Lib);
if (err) {
printf("FT_Init_FreeType returned %d\n", err);
return;
}

FT_Add_Default_Modules(m_Lib);
FT_Set_Default_Properties(m_Lib);
}
~FTLib() {
if (m_Lib) {
FT_Done_Library(m_Lib);
}
}

operator bool() const { return m_Lib != nullptr; }
};

struct FTFace {
sk_sp<SkData> m_Data;
FT_Face m_Face;

FTFace() : m_Face(nullptr) {}
~FTFace() {
if (m_Face) {
FT_Done_Face(m_Face);
}
}

bool load(FT_Library lib, sk_sp<SkData> data) {
int face_index = 0; // todo
int err = FT_New_Memory_Face(lib, (const FT_Byte*)data->data(),
data->size(), face_index, &m_Face);
if (err) {
printf("FT_New_Memory_Face returned %d\n", err);
return false;
}
m_Data = std::move(data);
return true;
}

operator bool() const { return m_Face != nullptr; }

int upem() const {
assert(m_Face);
return m_Face->units_per_EM;
}

bool setSize(int size) {
assert(m_Face);
int err = FT_Set_Char_Size(m_Face, size * 64, 0, 72, 72);
if (err) {
printf("failed to set size %d\n", size);
return false;
}
return true;
}

bool getPath(uint16_t glyph, PathSink* sink) {
unsigned flags = FT_LOAD_NO_HINTING | FT_LOAD_NO_BITMAP;
flags &= ~FT_LOAD_RENDER;

int err = FT_Load_Glyph(m_Face, glyph, flags);
assert(err == 0);

FTPathSinkCaller caller(sink);
err = FT_Outline_Decompose(&m_Face->glyph->outline,
&FTPathSinkCaller::Funcs,
&caller);
if (err) {
printf("failed calling decompose %d\n", err);
return false;
}
sink->close();
return true;
}
};

void test_fonts(const char path[]) {
FTLib lib;
if (!lib) {
printf("failed to init freetype\n");
return;
}

auto data = SkData::MakeFromFileName(path);
if (!data) {
printf("failed to load file %s\n", path);
return;
}

FTFace face;
if (!face.load(lib.m_Lib, data)) {
printf("failed to load file\n");
return;
}

printf("%s has %ld glyphs and %d upem\n",
path, face.m_Face->num_glyphs, face.m_Face->units_per_EM);

face.setSize(face.upem());

int glyph = FT_Get_Char_Index(face.m_Face, 'Q');
if (glyph == 0) {
printf("char2glyph failed\n");
return;
}

PathSink sink;
face.getPath(glyph, &sink);
}
8 changes: 6 additions & 2 deletions skia/viewer/src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -132,8 +132,12 @@ void glfwDropCallback(GLFWwindow* window, int count, const char** paths) {
initAnimation(0);
}

void test_fonts(const char path[]);

int main() {
if (!glfwInit()) {
test_fonts("/Users/mike/fonts/Skia.ttf");

if (!glfwInit()) {
fprintf(stderr, "Failed to initialize glfw.\n");
return 1;
}
Expand Down Expand Up @@ -373,4 +377,4 @@ int main() {
glfwTerminate();

return 0;
}
}

0 comments on commit 0f2cc50

Please sign in to comment.