Skip to content

Instantly share code, notes, and snippets.

@n-yoda
Last active September 20, 2015 06:34
Show Gist options
  • Save n-yoda/aa7a6090c783f9561ddc to your computer and use it in GitHub Desktop.
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.
/*
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