Skip to content

Commit 0f2cc50

Browse files
committed
try calling freetype
1 parent 3f104f0 commit 0f2cc50

File tree

3 files changed

+240
-6
lines changed

3 files changed

+240
-6
lines changed

skia/viewer/build/premake5.lua

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,17 +19,24 @@ includedirs {"../include", "../../../include", "../../renderer/include", "../../
1919
"../../dependencies/skia", "../../dependencies/skia/include/core",
2020
"../../dependencies/skia/include/effects", "../../dependencies/skia/include/gpu",
2121
"../../dependencies/skia/include/config", "../../dependencies/imgui", "../../dependencies",
22-
"../../dependencies/gl3w/build/include"}
22+
"../../dependencies/gl3w/build/include",
23+
"/Users/mike/other/freetype/include"
24+
}
2325

24-
links {"Cocoa.framework", "IOKit.framework", "CoreVideo.framework", "rive", "skia", "rive_skia_renderer", "glfw3"}
26+
links {
27+
"Cocoa.framework", "IOKit.framework", "CoreVideo.framework",
28+
"rive", "skia", "rive_skia_renderer", "glfw3",
29+
"freetype",
30+
}
2531
libdirs {"../../../build/%{cfg.system}/bin/%{cfg.buildcfg}", "../../dependencies/glfw_build/src",
26-
"../../dependencies/skia/out/static", "../../renderer/build/%{cfg.system}/bin/%{cfg.buildcfg}"}
32+
"../../dependencies/skia/out/static", "../../renderer/build/%{cfg.system}/bin/%{cfg.buildcfg}",}
2733

2834
files {"../src/**.cpp", "../../dependencies/gl3w/build/src/gl3w.c",
2935
"../../dependencies/imgui/backends/imgui_impl_glfw.cpp",
3036
"../../dependencies/imgui/backends/imgui_impl_opengl3.cpp", "../../dependencies/imgui/imgui_widgets.cpp",
3137
"../../dependencies/imgui/imgui.cpp", "../../dependencies/imgui/imgui_tables.cpp",
32-
"../../dependencies/imgui/imgui_draw.cpp"}
38+
"../../dependencies/imgui/imgui_draw.cpp",
39+
}
3340

3441
buildoptions {"-Wall", "-fno-exceptions", "-fno-rtti", "-flto=full"}
3542
filter "configurations:debug"

skia/viewer/src/fonts.cpp

Lines changed: 223 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,223 @@
1+
#include "rive/renderer.hpp"
2+
#include "SkData.h"
3+
4+
#include <ft2build.h>
5+
#include FT_FREETYPE_H
6+
7+
#include <freetype/ftadvanc.h>
8+
#include <freetype/ftimage.h>
9+
#include <freetype/ftbitmap.h>
10+
#ifdef FT_COLOR_H // 2.10.0
11+
# include <freetype/ftcolor.h>
12+
#endif
13+
#include <freetype/freetype.h>
14+
#include <freetype/ftlcdfil.h>
15+
#include <freetype/ftmodapi.h>
16+
#include <freetype/ftmm.h>
17+
#include <freetype/ftoutln.h>
18+
#include <freetype/ftsizes.h>
19+
#include <freetype/ftsystem.h>
20+
#include <freetype/tttables.h>
21+
#include <freetype/t1tables.h>
22+
#include <freetype/ftfntfmt.h>
23+
24+
25+
26+
27+
typedef struct FT_LibraryRec_* FT_Library;
28+
typedef struct FT_FaceRec_* FT_Face;
29+
typedef struct FT_StreamRec_* FT_Stream;
30+
typedef signed long FT_Pos;
31+
typedef struct FT_BBox_ FT_BBox;
32+
33+
struct PathSink {
34+
35+
void move(float x, float y) {
36+
printf("move %g %g\n", x, y);
37+
}
38+
void line(float x, float y) {
39+
printf("line %g %g\n", x, y);
40+
}
41+
void quad(float x0, float y0, float x1, float y1) {
42+
printf("quad %g %g %g %g\n", x0, y0, x1, y1);
43+
}
44+
void cubic(float x0, float y0, float x1, float y1, float x2, float y2) {
45+
printf("cube %g %g %g %g %g %g\n", x0, y0, x1, y1, x2, y2);
46+
}
47+
void close() {
48+
printf("close\n");
49+
}
50+
};
51+
52+
struct FTPathSinkCaller {
53+
private:
54+
PathSink* m_Sink;
55+
// we have to manually close contours
56+
bool m_ReadyToClose = false;
57+
58+
static inline float dot6tofloat(int32_t x) {
59+
return x * (1.0f/64);
60+
}
61+
62+
static int Move(const FT_Vector* pt, void* ctx) {
63+
auto caller = (FTPathSinkCaller*)ctx;
64+
if (caller->m_ReadyToClose) {
65+
caller->m_Sink->close();
66+
caller->m_ReadyToClose = false;
67+
}
68+
caller->m_Sink->move(dot6tofloat(pt->x), -dot6tofloat(pt->y));
69+
return 0;
70+
}
71+
72+
static int Line(const FT_Vector* pt, void* ctx) {
73+
auto caller = (FTPathSinkCaller*)ctx;
74+
caller->m_Sink->move(dot6tofloat(pt->x), -dot6tofloat(pt->y));
75+
caller->m_ReadyToClose = true;
76+
return 0;
77+
}
78+
79+
static int Quad(const FT_Vector* pt0, const FT_Vector* pt1, void* ctx) {
80+
auto caller = (FTPathSinkCaller*)ctx;
81+
caller->m_Sink->quad(dot6tofloat(pt0->x), -dot6tofloat(pt0->y),
82+
dot6tofloat(pt1->x), -dot6tofloat(pt1->y));
83+
caller->m_ReadyToClose = true;
84+
return 0;
85+
}
86+
87+
static int Cubic(const FT_Vector* pt0, const FT_Vector* pt1, const FT_Vector* pt2, void* ctx) {
88+
auto caller = (FTPathSinkCaller*)ctx;
89+
caller->m_Sink->cubic(dot6tofloat(pt0->x), -dot6tofloat(pt0->y),
90+
dot6tofloat(pt1->x), -dot6tofloat(pt1->y),
91+
dot6tofloat(pt2->x), -dot6tofloat(pt2->y));
92+
caller->m_ReadyToClose = true;
93+
return 0;
94+
}
95+
96+
public:
97+
FTPathSinkCaller(PathSink* sink) : m_Sink(sink) {}
98+
99+
inline static constexpr const FT_Outline_Funcs Funcs{
100+
FTPathSinkCaller::Move,
101+
FTPathSinkCaller::Line,
102+
FTPathSinkCaller::Quad,
103+
FTPathSinkCaller::Cubic,
104+
0, // shift
105+
0, // delta
106+
};
107+
};
108+
109+
struct FTLib {
110+
FT_Library m_Lib;
111+
112+
FTLib() : m_Lib(nullptr) {
113+
int err = FT_Init_FreeType(&m_Lib);
114+
if (err) {
115+
printf("FT_Init_FreeType returned %d\n", err);
116+
return;
117+
}
118+
119+
FT_Add_Default_Modules(m_Lib);
120+
FT_Set_Default_Properties(m_Lib);
121+
}
122+
~FTLib() {
123+
if (m_Lib) {
124+
FT_Done_Library(m_Lib);
125+
}
126+
}
127+
128+
operator bool() const { return m_Lib != nullptr; }
129+
};
130+
131+
struct FTFace {
132+
sk_sp<SkData> m_Data;
133+
FT_Face m_Face;
134+
135+
FTFace() : m_Face(nullptr) {}
136+
~FTFace() {
137+
if (m_Face) {
138+
FT_Done_Face(m_Face);
139+
}
140+
}
141+
142+
bool load(FT_Library lib, sk_sp<SkData> data) {
143+
int face_index = 0; // todo
144+
int err = FT_New_Memory_Face(lib, (const FT_Byte*)data->data(),
145+
data->size(), face_index, &m_Face);
146+
if (err) {
147+
printf("FT_New_Memory_Face returned %d\n", err);
148+
return false;
149+
}
150+
m_Data = std::move(data);
151+
return true;
152+
}
153+
154+
operator bool() const { return m_Face != nullptr; }
155+
156+
int upem() const {
157+
assert(m_Face);
158+
return m_Face->units_per_EM;
159+
}
160+
161+
bool setSize(int size) {
162+
assert(m_Face);
163+
int err = FT_Set_Char_Size(m_Face, size * 64, 0, 72, 72);
164+
if (err) {
165+
printf("failed to set size %d\n", size);
166+
return false;
167+
}
168+
return true;
169+
}
170+
171+
bool getPath(uint16_t glyph, PathSink* sink) {
172+
unsigned flags = FT_LOAD_NO_HINTING | FT_LOAD_NO_BITMAP;
173+
flags &= ~FT_LOAD_RENDER;
174+
175+
int err = FT_Load_Glyph(m_Face, glyph, flags);
176+
assert(err == 0);
177+
178+
FTPathSinkCaller caller(sink);
179+
err = FT_Outline_Decompose(&m_Face->glyph->outline,
180+
&FTPathSinkCaller::Funcs,
181+
&caller);
182+
if (err) {
183+
printf("failed calling decompose %d\n", err);
184+
return false;
185+
}
186+
sink->close();
187+
return true;
188+
}
189+
};
190+
191+
void test_fonts(const char path[]) {
192+
FTLib lib;
193+
if (!lib) {
194+
printf("failed to init freetype\n");
195+
return;
196+
}
197+
198+
auto data = SkData::MakeFromFileName(path);
199+
if (!data) {
200+
printf("failed to load file %s\n", path);
201+
return;
202+
}
203+
204+
FTFace face;
205+
if (!face.load(lib.m_Lib, data)) {
206+
printf("failed to load file\n");
207+
return;
208+
}
209+
210+
printf("%s has %ld glyphs and %d upem\n",
211+
path, face.m_Face->num_glyphs, face.m_Face->units_per_EM);
212+
213+
face.setSize(face.upem());
214+
215+
int glyph = FT_Get_Char_Index(face.m_Face, 'Q');
216+
if (glyph == 0) {
217+
printf("char2glyph failed\n");
218+
return;
219+
}
220+
221+
PathSink sink;
222+
face.getPath(glyph, &sink);
223+
}

skia/viewer/src/main.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -132,8 +132,12 @@ void glfwDropCallback(GLFWwindow* window, int count, const char** paths) {
132132
initAnimation(0);
133133
}
134134

135+
void test_fonts(const char path[]);
136+
135137
int main() {
136-
if (!glfwInit()) {
138+
test_fonts("/Users/mike/fonts/Skia.ttf");
139+
140+
if (!glfwInit()) {
137141
fprintf(stderr, "Failed to initialize glfw.\n");
138142
return 1;
139143
}
@@ -373,4 +377,4 @@ int main() {
373377
glfwTerminate();
374378

375379
return 0;
376-
}
380+
}

0 commit comments

Comments
 (0)