瀏覽代碼

Generate a bunch of characters

rexim 5 年之前
父節點
當前提交
9123287811
共有 3 個文件被更改,包括 108 次插入3 次删除
  1. 2 1
      .gitignore
  2. 6 1
      Makefile
  3. 100 1
      main.cpp

+ 2 - 1
.gitignore

@@ -1 +1,2 @@
-vodus
+vodus
+*.ppm

+ 6 - 1
Makefile

@@ -1,2 +1,7 @@
+CXXFLAGS=-Wall -O0 -fno-builtin -ggdb $(shell pkg-config --cflags freetype2)
+LIBS=$(shell pkg-config --libs freetype2)
+
+all: vodus Makefile
+
 vodus: main.cpp
-	clang++ -Wall -o vodus main.cpp
+	clang++ $(CXXFLAGS) -o vodus main.cpp $(LIBS)

+ 100 - 1
main.cpp

@@ -1,8 +1,107 @@
+#include <cassert>
 #include <cstdio>
 
+#include <ft2build.h>
+#include FT_FREETYPE_H
+
+#define FACE_FILE_PATH "/usr/share/fonts/opentype/comic-neue/ComicNeue_Oblique.otf"
+
+int save_bitmap_as_ppm(FT_Bitmap *bitmap,
+                       char prefix_char)
+{
+    assert(bitmap->pixel_mode == FT_PIXEL_MODE_GRAY);
+
+    char filename[10];
+    snprintf(filename, 10, "%c.ppm", prefix_char);
+
+    FILE *f = fopen(filename, "wb");
+    if (!f) return -1;
+
+    fprintf(f,
+            "P6\n"
+            "%d %d\n"
+            "255\n",
+            bitmap->width,
+            bitmap->rows);
+
+    for (int row = 0; row < bitmap->rows; ++row) {
+        for (int col = 0; col < bitmap->width; ++col) {
+            char x = *(bitmap->buffer + bitmap->pitch * row + col);
+            fputc(x, f);
+            fputc(x, f);
+            fputc(x, f);
+        }
+    }
+
+    fclose(f);
+    return 0;
+}
+
 int main(int argc, char *argv[])
 {
-    printf("Hello, Vodus\n");
+    FT_Library library;
+    auto error = FT_Init_FreeType(&library);
+    if (error) {
+        fprintf(stderr, "Could not initialize FreeType2\n");
+        exit(1);
+    }
+
+    FT_Face face;
+    error = FT_New_Face(library,
+                        FACE_FILE_PATH,
+                        0,
+                        &face);
+    if (error == FT_Err_Unknown_File_Format) {
+        fprintf(stderr,
+                "%s appears to have an unsuppoted format\n",
+                FACE_FILE_PATH);
+        exit(1);
+    } else if (error) {
+        fprintf(stderr,
+                "%s could not be opened\n",
+                FACE_FILE_PATH);
+        exit(1);
+    }
+
+    printf("Loaded %s\n", FACE_FILE_PATH);
+    printf("\tnum_glyphs = %ld\n", face->num_glyphs);
+
+    error = FT_Set_Pixel_Sizes(face, 0, 64);
+    if (error) {
+        fprintf(stderr, "Could not set font size in pixels\n");
+        exit(1);
+    }
+
+    const char *text = "abcd";
+    while (*text != '\0') {
+        auto glyph_index = FT_Get_Char_Index(face, *text);
+        error = FT_Load_Glyph(
+            face,
+            glyph_index,
+            0);
+
+        if (error) {
+            fprintf(stderr, "Could not load glyph for %c\n", *text);
+            exit(1);
+        }
+
+        error = FT_Render_Glyph(face->glyph,
+                                FT_RENDER_MODE_NORMAL);
+        if (error) {
+            fprintf(stderr, "Could not render glyph for %c\n", *text);
+            exit(1);
+        }
+
+        printf("\t'%c'\n", *text);
+        printf("\t\tglyph_index: %ld\n", glyph_index);
+        printf("\t\trows: %ld\n", face->glyph->bitmap.rows);
+        printf("\t\twidth: %ld\n", face->glyph->bitmap.width);
+        printf("\t\tpixel_mode: %ld\n", face->glyph->bitmap.pixel_mode);
+
+        save_bitmap_as_ppm(&face->glyph->bitmap, *text);
+
+        text++;
+    }
 
     return 0;
 }