Forked from simoncozens/gist:6892796dd737212b0651
Last active
August 29, 2015 14:14
-
-
Save sneetsher/2050aa7657804281fdd5 to your computer and use it in GitHub Desktop.
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
#include <stdlib.h> | |
#include <stdio.h> | |
#include <assert.h> | |
#include <ft2build.h> | |
#include FT_FREETYPE_H | |
#include FT_GLYPH_H | |
#include FT_OUTLINE_H | |
#include <hb.h> | |
#include <hb-ft.h> | |
#include <fontconfig/fontconfig.h> | |
typedef struct { | |
char* family; | |
char* lang; | |
double pointSize; | |
int weight; | |
int direction; | |
int slant; | |
char* style; | |
char* script; | |
} fontOptions; | |
typedef struct { | |
double width; | |
double height; | |
double depth; | |
} box; | |
static char* get_font_path(fontOptions f) { | |
FcResult result; | |
FcChar8* filename; | |
char* filename2; | |
int id; | |
FcPattern* matched; | |
FcPattern* p = FcPatternCreate(); | |
FcPatternAddString (p, FC_FAMILY, (FcChar8*)(f.family)); | |
FcPatternAddDouble (p, FC_SIZE, f.pointSize); | |
if (f.slant) | |
FcPatternAddInteger(p, FC_SLANT, f.slant); | |
if (f.weight) | |
FcPatternAddInteger(p, FC_WEIGHT, f.weight); | |
/* Add fallback fonts here. Some of the standard 14 should be fine. */ | |
FcPatternAddString (p, FC_FAMILY,(FcChar8*) "Times-Roman"); | |
FcPatternAddString (p, FC_FAMILY,(FcChar8*) "Times"); | |
FcPatternAddString (p, FC_FAMILY,(FcChar8*) "Helvetica"); | |
matched = FcFontMatch (0, p, &result); | |
if (FcPatternGetString (matched, FC_FILE, 0, &filename) != FcResultMatch) | |
return NULL; | |
if (FcPatternGetInteger (matched, FC_INDEX, 0, &id) != FcResultMatch) | |
return NULL; | |
filename2 = malloc(strlen(filename)); /* Because otherwise destroying the pattern will reclaim it. */ | |
strcpy(filename2, (char*)filename); | |
FcPatternDestroy (matched); | |
FcPatternDestroy (p); | |
return filename2; | |
} | |
void calculate_extents(box* b, hb_glyph_info_t glyph_info, hb_glyph_position_t glyph_pos, FT_Face ft_face) { | |
const FT_Error error = FT_Load_Glyph(ft_face, glyph_info.codepoint, FT_LOAD_DEFAULT); | |
if (error) return; | |
const FT_Glyph_Metrics *ftmetrics = &ft_face->glyph->metrics; | |
b->width = glyph_pos.x_advance /64.0; | |
b->height = ftmetrics->horiBearingY / 64.0; | |
b->depth = (ftmetrics->height - ftmetrics->horiBearingY) / 64.0; | |
} | |
int main (int argc, char** argv) { | |
FT_Library ft_library; | |
char * font_path; | |
int device_hdpi = 72; | |
int device_vdpi = 72; | |
char * text = argv[1]; | |
fontOptions f = { | |
.pointSize = 12, | |
.lang = "en", | |
.family = "Adobe Garamond Pro", | |
.script = "latin", | |
.direction = HB_DIRECTION_LTR, | |
.weight = 200, | |
}; | |
FT_Face ft_face; | |
unsigned int glyph_count; | |
hb_font_t *hb_ft_font; | |
hb_buffer_t *buf; | |
hb_glyph_info_t *glyph_info; | |
hb_glyph_position_t *glyph_pos; | |
box glyph_extents; | |
unsigned int j; | |
assert(!FT_Init_FreeType(&ft_library)); | |
font_path = get_font_path(f); | |
printf("Using %s\n", font_path); | |
assert(!FT_New_Face(ft_library, font_path, 0, &ft_face)); | |
assert(!FT_Set_Char_Size(ft_face, 0, f.pointSize * 64, device_hdpi, device_vdpi )); | |
/* Get our harfbuzz font structs */ | |
hb_ft_font = hb_ft_font_create(ft_face, NULL); | |
buf = hb_buffer_create(); | |
if (f.script) | |
hb_buffer_set_script(buf, hb_tag_from_string(f.script, strlen(f.script))); | |
if (f.direction) | |
hb_buffer_set_direction(buf, f.direction); | |
if (f.lang) | |
hb_buffer_set_language(buf, hb_language_from_string(f.lang,strlen(f.lang))); | |
hb_buffer_add_utf8(buf, text, strlen(text), 0, strlen(text)); | |
hb_shape(hb_ft_font, buf, NULL, 0); | |
glyph_info = hb_buffer_get_glyph_infos(buf, &glyph_count); | |
glyph_pos = hb_buffer_get_glyph_positions(buf, &glyph_count); | |
for (j = 0; j < glyph_count; ++j) { | |
calculate_extents(&glyph_extents, glyph_info[j], glyph_pos[j], ft_face); | |
printf("CP: %d, <%f> ^%f v%f\n", glyph_info[j].codepoint, glyph_extents.width, glyph_extents.height, glyph_extents.depth); | |
} | |
hb_buffer_destroy(buf); | |
hb_font_destroy(hb_ft_font); | |
FT_Done_FreeType(ft_library); | |
free(font_path); | |
return 0; | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment