freetype curve extraction in Font.java and readback in Box.java
[org.ibex.core.git] / src / org / ibex / graphics / Freetype.c
index 4387aec..62a2f7c 100644 (file)
@@ -119,6 +119,53 @@ int load_font(char *buf, int length) {
     return FT_New_Memory_Face(library, buf, length, 0, &face);
 }
 
+// if the path is more than 16k chars long, we're screwed anyways...
+static char path[1024 * 16];
+static int pathlen = 0;
+static int current_x;
+static int current_y;
+
+static void append(FT_Pos x, FT_Pos y) {
+    sprintf(path + pathlen, "%d,%d ", x - current_x, y - current_y);
+    pathlen += strlen(path + pathlen);
+}
+static int moveto(FT_Vector* to, void* user) {
+    if (pathlen > 0) {
+        path[pathlen++] = 'z';
+        path[pathlen++] = ' ';
+    }
+    path[pathlen++] = 'm';
+    path[pathlen++] = ' ';
+    append(to->x, to->y);
+    current_x = to->x; current_y = to->y;
+    return 0;
+}
+static int lineto(FT_Vector* to, void* user) {
+    path[pathlen++] = 'l';
+    path[pathlen++] = ' ';
+    append(to->x, to->y);
+    current_x = to->x; current_y = to->y;
+    return 0;
+}
+static int conicto(FT_Vector* control, FT_Vector*  to, void* user) {
+    path[pathlen++] = 'q';
+    path[pathlen++] = ' ';
+    append(control->x, control->y);
+    append(to->x, to->y);
+    current_x = to->x; current_y = to->y;
+    return 0;
+}
+static int cubicto(FT_Vector* control1, FT_Vector* control2, FT_Vector* to, void* user) {
+    path[pathlen++] = 'c';
+    path[pathlen++] = ' ';
+    append(control1->x, control1->y);
+    append(control2->x, control2->y);
+    append(to->x, to->y);
+    current_x = to->x; current_y = to->y;
+    return 0;
+}
+static FT_Outline_Funcs buildPath = { &moveto, &lineto, &conicto, &cubicto, 0, 0 };
+
 int render(int charcode, int size) __attribute__((section(".text")));
 int render(int charcode, int size) {
     int glyph_index;
@@ -136,6 +183,17 @@ int render(int charcode, int size) {
     user_info[4]  = (-1 * face->size->metrics.descender) >> 6;
     user_info[5] = face->glyph->metrics.horiBearingY >> 6;
     user_info[6] = face->glyph->advance.x >> 6;
+
+    pathlen = 0; current_x = 0; current_y = 0;
+    FT_Outline_Decompose(&face->glyph->outline, &buildPath, NULL);
+    path[pathlen++] = 'z';
+    path[pathlen++] = ' ';
+    path[pathlen++] = 'm';
+    path[pathlen++] = ' ';
+    append(0, 0);
+    path[pathlen++] = ' ';
+    user_info[7] = (int)&path;
+    user_info[8] = pathlen;
 }
 
 // Kerning code; add back in later