The Birdfont Source Code


All Repositories / birdfont.git / blob – RSS feed

overview_glyph.c in /libbirdfont

This file is a part of the Birdfont project.

Contributing

Send patches or pull requests to johan.mattsson.m@gmail.com.
Clone this repository: git clone https://github.com/johanmattssonm/birdfont.git
Circle boundaries heads/master
1 /* 2 Copyright (C) 2015 Johan Mattsson 3 4 This library is free software; you can redistribute it and/or modify 5 it under the terms of the GNU Lesser General Public License as 6 published by the Free Software Foundation; either version 3 of the 7 License, or (at your option) any later version. 8 9 This library is distributed in the hope that it will be useful, but 10 WITHOUT ANY WARRANTY; without even the implied warranty of 11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 Lesser General Public License for more details. 13 */ 14 15 #include <assert.h> 16 #include <glib.h> 17 #include <stdio.h> 18 #include <cairo.h> 19 #include <cairo-ft.h> 20 #include <stdlib.h> 21 #include <ft2build.h> 22 #include FT_FREETYPE_H 23 #include FT_GLYPH_H 24 25 FT_Library freetype_library = NULL; 26 27 gboolean draw_overview_glyph (cairo_t* context, const char* font_file, gdouble width, gdouble height, gunichar character) { 28 FT_Face face; 29 int error; 30 gdouble units_per_em; 31 gdouble units; 32 gdouble advance; 33 int gid; 34 35 // private use area 36 if (0xe000 <= character && character <= 0xf8ff) { 37 return FALSE; 38 } 39 40 // control characters 41 if (character <= 0x001f || (0x007f <= character && character <= 0x008d)) { 42 return FALSE; 43 } 44 45 if (font_file == NULL) { 46 g_warning("font_file is null"); 47 return FALSE; 48 } 49 50 gchar text[7]; 51 int length = g_unichar_to_utf8 (character, text); 52 text[length] = '\0'; 53 54 if (freetype_library == NULL) { 55 error = FT_Init_FreeType (&freetype_library); 56 if (error) { 57 g_warning ("Freetype init error %d.\n", error); 58 return FALSE; 59 } 60 } 61 62 error = FT_New_Face (freetype_library, font_file, 0, &face); 63 if (error) { 64 g_warning ("Freetype font face error %d\n", error); 65 return FALSE; 66 } 67 68 units_per_em = face->units_per_EM; 69 units = (height * 0.5) / units_per_em; 70 71 error = FT_Select_Charmap (face , FT_ENCODING_UNICODE); 72 if (error) { 73 g_warning ("Freetype can not use Unicode, error: %d\n", error); 74 FT_Done_Face (face); 75 return FALSE; 76 } 77 78 error = FT_Set_Char_Size (face, 0, 64, (int) height, (int) height); 79 if (error) { 80 g_warning ("FT_Set_Char_Size, error: %d.\n", error); 81 FT_Done_Face (face); 82 return FALSE; 83 } 84 85 error = FT_Set_Pixel_Sizes (face, 0, (int) (height * 0.5)); 86 if (error) { 87 g_warning ("FT_Set_Pixel_Sizes, error: %d.\n", error); 88 FT_Done_Face (face); 89 return FALSE; 90 } 91 92 gid = FT_Get_Char_Index (face, character); 93 advance = 0; 94 if (gid != 0) { 95 FT_Load_Glyph(face, gid, FT_LOAD_DEFAULT | FT_LOAD_NO_BITMAP | FT_LOAD_NO_SCALE); 96 advance = face->glyph->metrics.horiAdvance; 97 advance *= units; 98 } else { 99 FT_Done_Face (face); 100 return FALSE; 101 } 102 103 static const cairo_user_data_key_t key; 104 105 cairo_save (context); 106 107 cairo_font_face_t* cairo_face = cairo_ft_font_face_create_for_ft_face (face, 0); 108 109 if (cairo_face == NULL) { 110 g_warning("cairo font face is null"); 111 FT_Done_Face (face); 112 return FALSE; 113 } 114 115 int status = cairo_font_face_set_user_data (cairo_face, &key, face, (cairo_destroy_func_t) FT_Done_Face); 116 117 if (status != CAIRO_STATUS_SUCCESS) { 118 cairo_font_face_destroy (cairo_face); 119 FT_Done_Face (face); 120 return FALSE; 121 } 122 123 cairo_set_font_face (context, cairo_face); 124 cairo_set_font_size (context, height * 0.5); 125 126 gdouble x = (width - advance) / 2; 127 128 if (x < 0) { 129 x = 0; 130 } 131 132 cairo_move_to (context, x, height - 30); 133 cairo_show_text (context, text); 134 135 cairo_font_face_destroy (cairo_face); 136 cairo_restore (context); 137 138 // cairo closes the font face and the library must be kept open 139 140 return TRUE; 141 } 142