Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Font utilities

  • Loading branch information...
commit 4fc64bbe9b0007f83a4c272bc6faf41dfbeacb0c 1 parent 56fa082
@sbourdeauducq sbourdeauducq authored
Showing with 311 additions and 0 deletions.
  1. +10 −0 ttf2tff/Makefile
  2. +140 −0 ttf2tff/tffview.c
  3. +161 −0 ttf2tff/ttf2tff.c
View
10 ttf2tff/Makefile
@@ -0,0 +1,10 @@
+
+FT_CFLAGS = -I/usr/include/freetype2
+
+all: tffview ttf2tff
+
+tffview: tffview.c
+ gcc -lSDL $^ -o $@
+
+ttf2tff: ttf2tff.c
+ gcc $(FT_CFLAGS) -lfreetype $^ -o $@
View
140 ttf2tff/tffview.c
@@ -0,0 +1,140 @@
+/*
+ * \brief Viewer for tff (trivial font format) font files
+ * \date 2005-11-07
+ * \author Norman Feske
+ */
+
+#include <SDL/SDL.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/stat.h>
+
+typedef unsigned char u8;
+typedef unsigned short u16;
+typedef unsigned long u32;
+
+
+/**
+ * Multiply 16bit color with alpha value
+ */
+static inline u16 blend(u16 color, int alpha)
+{
+ return ((((alpha >> 3) * (color & 0xf81f)) >> 5) & 0xf81f)
+ | (((alpha * (color & 0x07e0)) >> 8) & 0x7e0);
+}
+
+
+/**
+ * Find highest value in array
+ */
+static int highest(u32 *buf, int num)
+{
+ int i, max = 0;
+ for (i = 0; i < num; i++)
+ if (buf[i] > max) max = buf[i];
+ return max;
+}
+
+
+/**
+ * Draw single character
+ */
+static void draw_char(u8 *src, int src_w, int w, int h, u16 *dst, int dst_w)
+{
+ int x, y;
+ for (y = 0; y < h; y++)
+ for (x = 0; x < w; x++)
+ dst[y*dst_w + x] = blend(0xffff, src[y*src_w + x]);
+}
+
+
+/**
+ * Draw a tinted box
+ */
+static void tint(u16 *dst, int dst_w, int w, int h, u16 color)
+{
+ int x, y;
+ for (y = 0; y < h; y++)
+ for (x = 0; x < w; x++)
+ dst[y*dst_w + x] |= color;
+}
+
+
+/**
+ * Main program
+ */
+int main(int argc, char **argv)
+{
+ SDL_Surface *screen;
+ SDL_Event event;
+ u8 *tff;
+ u16 *scr_adr;
+ int x, y;
+ u32 otab[256], wtab[256];
+ u8 *img;
+ u32 cw, w, h;
+
+ if (argc < 2) {
+ printf("\nusage:\n\n tffview <fontfile>\n\n");
+ return 0;
+ }
+
+ int fh = open(argv[1], O_RDONLY);
+ if (fh < 0) {
+ printf("Error: Could not open file %d for reading.\n", (int)argv[1]);
+ return -1;
+ }
+
+ int cnt = 0;
+ cnt += read(fh, otab, sizeof(otab));
+ cnt += read(fh, wtab, sizeof(wtab));
+ cnt += read(fh, &w, sizeof(w));
+ cnt += read(fh, &h, sizeof(h));
+
+ if (cnt != 1024*2 + 8) {
+ printf("Error: Could not read %d bytes from font file\n", 1024*2 + 8);
+ return -1;
+ }
+
+ cw = highest(wtab, 256);
+
+ printf("Size of font image is %dx%d, character cell is %dx%d.\n",
+ (int)w, (int)h, (int)cw, (int)h);
+
+ if (!(img = malloc(w*h))) {
+ printf("Error: Could not allocate %d bytes for font image\n", (int)(w*h));
+ return -1;
+ }
+
+ if (read(fh, img, w*h) != w*h) {
+ printf("Error: Could not read font image from font file\n");
+ return -1;
+ }
+
+ if (SDL_Init(SDL_INIT_VIDEO) < 0) return 0;
+
+ screen = SDL_SetVideoMode(cw*16, h*16, 16, SDL_SWSURFACE);
+ scr_adr = (u16 *)(screen->pixels);
+
+ for (y = 0; y < 16; y++)
+ for (x = 0; x < 16; x++) {
+ int n = y*16 + x;
+ u16 *d = scr_adr + x*cw + y*16*cw*h;
+ draw_char(img + otab[n], w, wtab[n], h, d, cw*16);
+ tint(d, cw*16, cw, h, (x + y) & 1 ? 0 : 0x3800);
+ }
+
+ SDL_UpdateRect(screen, 0, 0, 16*cw, 16*h);
+
+ while (1) {
+ SDL_WaitEvent(&event);
+ switch (event.type) {
+ case SDL_KEYDOWN:
+ case SDL_QUIT:
+ return 0;
+ }
+ }
+
+ return 0;
+}
View
161 ttf2tff/ttf2tff.c
@@ -0,0 +1,161 @@
+/*
+ * \brief Convert truetype fonts to trivial font format
+ * \date 2005-11-07
+ * \author Norman Feske
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include <ft2build.h>
+#include FT_FREETYPE_H
+
+typedef unsigned char u8;
+typedef unsigned short u16;
+typedef unsigned long u32;
+
+
+void draw_bitmap(u8 *dst, int dst_w, int w, int h, u8 *src, int src_w) {
+ int x, y;
+ for (y = 0; y < h; y++) {
+ for (x = 0; x < w; x++)
+ dst[x] = src[x];
+ src += src_w;
+ dst += dst_w;
+ }
+}
+
+
+static int max(int a, int b) { return a > b ? a : b; }
+
+
+/**
+ * Main program
+ */
+int main(int argc, char **argv)
+{
+ static FT_Library library;
+ static FT_Face face;
+ static FT_GlyphSlot slot;
+ static u32 otab[256], wtab[256];
+ u32 img_w, img_h;
+ int img_l;
+ int res, i;
+ int size = 16*64;
+ u8 *img;
+
+ if (argc != 4) {
+ printf("\nConvert truetype fonts to trivial font format\n");
+ printf("\nusage:\n\n ttf2tff <source-ttf> <points> <destination-tff>\n\n");
+ return 0;
+ }
+
+ if ((res = FT_Init_FreeType(&library))) {
+ printf("Error: FT_Init_FreeType returned %d\n", res);
+ return -1;
+ }
+
+ if ((res = FT_New_Face(library, argv[1], 0, &face))) {
+ printf("Error: FT_New_Face returned %d - invalid font file?\n", res);
+ return -1;
+ }
+
+ size = atof(argv[2])*64;
+
+ printf("size = %d\n", size);
+ printf("num_faces = %d\n", (int)face->num_faces);
+ printf("num_glyphs = %d\n", (int)face->num_glyphs);
+ printf("face_flags = 0x08%x\n", (int)face->face_flags);
+
+ slot = face->glyph;
+
+ if ((res = FT_Set_Char_Size(face, 0, size, 0, 0))) {
+ printf("Error: FT_Set_Char_Size returned %d\n", res);
+ return;
+ }
+
+ /* calculate dimensions of font image */
+ img_w = 0;
+ img_h = 0;
+ img_l = 0;
+ for (i = 0; i < 256; i++) {
+ int w, h, l;
+
+ if (FT_Load_Char(face, i, FT_LOAD_RENDER | FT_LOAD_TARGET_LIGHT))
+ continue;
+
+ w = max(slot->bitmap.width, slot->advance.x >> 6);
+ h = slot->bitmap.rows;
+ l = slot->bitmap.rows - slot->bitmap_top;
+
+ wtab[i] = w;
+ otab[i] = img_w;
+
+ img_w += w;
+ img_h = h > img_h ? h : img_h;
+ img_l = l > img_l ? l : img_l;
+ }
+ printf("font image is %dx%d (lowline at -%d) pixels\n",
+ (int)img_w, (int)img_h, (int)img_l);
+
+ /* allocate font image */
+ if (!(img = malloc(img_w*(img_h + 50)))) {
+ printf("Error: Could not allocate %d bytes for font image\n", (int)(img_w*img_h));
+ return -1;
+ }
+ bzero(img, img_w*img_h);
+
+ /* draw glyphs into font image */
+ int pen_x = 0;
+ for (i = 0; i < 256; i++) {
+ int x, y, w, h;
+ u8 *s;
+
+ if (FT_Load_Char(face, i, FT_LOAD_RENDER | FT_LOAD_TARGET_LIGHT))
+ continue;
+
+ s = slot->bitmap.buffer;
+ x = otab[i];
+ w = slot->bitmap.width;
+
+ if (w < wtab[i]) {
+ x += (wtab[i] - w) >> 1;
+ }
+ if (slot->bitmap_left < 0) {
+ s -= slot->bitmap_left;
+ w += slot->bitmap_left;
+ }
+ y = img_h - slot->bitmap_top;
+ h = slot->bitmap.rows;
+
+ draw_bitmap(img + x + y*img_w, img_w, w, h, s, slot->bitmap.pitch);
+
+ pen_x += wtab[i];
+ }
+
+ img_h += img_l;
+
+ /* write tff file */
+ int fh = creat(argv[3], S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH);
+ if (fh < 0) {
+ printf("Error: Could not open file %s for writing\n", argv[3]);
+ return -1;
+ }
+
+ int cnt = 0;
+ cnt += write(fh, otab, sizeof(otab));
+ cnt += write(fh, wtab, sizeof(wtab));
+ cnt += write(fh, &img_w, sizeof(img_w));
+ cnt += write(fh, &img_h, sizeof(img_h));
+ cnt += write(fh, img, img_w*img_h);
+
+ if (cnt != sizeof(otab) + sizeof(wtab) + sizeof(img_w) + sizeof(img_h) + img_w*img_h) {
+ printf("Error: Write error\n");
+ return -1;
+ }
+ close(fh);
+
+ return 0;
+}
Please sign in to comment.
Something went wrong with that request. Please try again.