Last active
September 20, 2015 06:34
-
-
Save n-yoda/aa7a6090c783f9561ddc to your computer and use it in GitHub Desktop.
FreeType example. Load font file and export a specified glyph shape as a graphviz dot file.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
gcc -I/usr/local/include/freetype2 -lfreetype glyph2dot.c -o glyph2dot | |
./glyph2dot hoge.ttf 0 A | dot -Kfdp -n -Tpng -o A.png | |
*/ | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <ft2build.h> | |
#include FT_FREETYPE_H | |
const char* getErrorMessage(FT_Error err) | |
{ | |
#undef __FTERRORS_H__ | |
#define FT_ERRORDEF( e, v, s ) case e: return s; | |
#define FT_ERROR_START_LIST | |
#define FT_ERROR_END_LIST | |
switch (err) { | |
#include FT_ERRORS_H | |
} | |
return "(Unknown error)"; | |
} | |
void exitOnError(FT_Error err) | |
{ | |
if (err) | |
{ | |
printf("%s\n", getErrorMessage(err)); | |
exit(1); | |
} | |
} | |
int main(int argc, char** args) | |
{ | |
// Initialize library | |
FT_Library lib; | |
exitOnError(FT_Init_FreeType(&lib)); | |
if (argc < 2) | |
{ | |
printf("Usage: ./glyph2dot font-path [index] [char]\n"); | |
return 1; | |
} | |
// Load font | |
FT_Face face; | |
int faceIndex = argc >= 3 ? atoi(args[2]) : 0; | |
exitOnError(FT_New_Face(lib, args[1], faceIndex, &face)); | |
// Load glyph | |
char ch = argc >= 4 ? args[3][0] : 'A'; | |
exitOnError(FT_Load_Char(face, ch, FT_LOAD_NO_SCALE)); | |
FT_Outline* outline = &face->glyph->outline; | |
// Output outline as dot | |
int start = 0; | |
double scale = 0.002; | |
printf("digraph {\n"); | |
printf("overlap=true;\n"); | |
for (int i = 0; i < outline->n_contours; i ++) | |
{ | |
for (int j = start; j <= outline->contours[i]; j ++) | |
printf("p%d [shape=point pos=\"%f,%f!\"]\n", | |
j, outline->points[j].x * scale, outline->points[j].y * scale); | |
int onStart = start; | |
while(!(outline->tags[onStart] & 1)) onStart ++; | |
int before = onStart; | |
for (int j = onStart + 1; j <= outline->contours[i]; j ++) | |
{ | |
if (outline->tags[j] & 1) | |
{ | |
printf("p%d -> p%d\n", before, j); | |
before = j; | |
} | |
} | |
printf("p%d -> p%d\n", before, onStart); | |
start = outline->contours[i] + 1; | |
} | |
printf("}\n"); | |
// Release | |
FT_Done_Face(face); | |
FT_Done_FreeType(lib); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment