read.c revision 6ef05171
1/* $XdotOrg: xc/programs/fonttosfnt/read.c,v 1.2 2004/04/23 19:54:32 eich Exp $ */ 2/* 3Copyright (c) 2002 by Juliusz Chroboczek 4 5Permission is hereby granted, free of charge, to any person obtaining a copy 6of this software and associated documentation files (the "Software"), to deal 7in the Software without restriction, including without limitation the rights 8to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9copies of the Software, and to permit persons to whom the Software is 10furnished to do so, subject to the following conditions: 11 12The above copyright notice and this permission notice shall be included in 13all copies or substantial portions of the Software. 14 15THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21THE SOFTWARE. 22*/ 23/* $XdotOrg: xc/programs/fonttosfnt/read.c,v 1.2 2004/04/23 19:54:32 eich Exp $ */ 24/* $XFree86: xc/programs/fonttosfnt/read.c,v 1.5 2003/12/19 02:05:39 dawes Exp $ */ 25 26#include <stdio.h> 27 28#include <ft2build.h> 29#include FT_FREETYPE_H 30#include FT_BDF_H 31#include "X11/Xos.h" 32#include "fonttosfnt.h" 33#include "X11/fonts/fontenc.h" 34 35#define FLOOR2(x, y) ((x) >= 0 ? (x) / (y) : -(((-(x)) + (y) - 1) / (y))) 36#define CEIL2(x, y) (FLOOR2((x) + (y) - 1, (y))) 37#define FT_Pos_DOWN(x) (FLOOR2((x),64)) 38#define FT_Pos_UP(x) (CEIL2((x), 64)) 39 40static int ft_inited = 0; 41static FT_Library ft_library; 42 43static int 44FT_Ensure_Inited(void) 45{ 46 int rc; 47 if(ft_inited) 48 return 0; 49 50 rc = FT_Init_FreeType(&ft_library); 51 if(rc != 0) 52 return rc; 53 54 ft_inited = 1; 55 return 0; 56} 57 58int 59readFile(char *filename, FontPtr font) 60{ 61 int j, k, index; 62 int rc; 63 FT_Face face; 64 StrikePtr strike; 65 BitmapPtr bitmap; 66 int symbol = 0; 67 char *encoding_name = NULL; 68 FontMapPtr mapping = NULL; 69 FontMapReversePtr reverse = NULL; 70 71 72 rc = FT_Ensure_Inited(); 73 if(rc != 0) 74 return rc; 75 76 rc = FT_New_Face(ft_library, filename, 0, &face); 77 if(rc != 0) { 78 fprintf(stderr, "Couldn't open face %s.\n", filename); 79 return -1; 80 } 81 82 encoding_name = faceEncoding(face); 83 if(encoding_name == NULL) { 84 symbol = 1; 85 } else if(strcasecmp(encoding_name, "iso10646-1") != 0) { 86 if(reencode_flag) 87 mapping = FontEncMapFind(encoding_name, 88 FONT_ENCODING_UNICODE, 0, 0, NULL); 89 if(mapping == NULL) { 90 symbol = 1; 91 } else { 92 reverse = FontMapReverse(mapping); 93 if(reverse == NULL) { 94 fprintf(stderr, "Couldn't reverse mapping.\n"); 95 return -1; 96 } 97 } 98 } 99 100 if(verbose_flag) { 101 fprintf(stderr, "%s %s %s: %d sizes%s\n", 102 filename, face->family_name, face->style_name, 103 face->num_fixed_sizes, 104 symbol ? " (symbol)" : ""); 105 } 106 107 if(font->numNames == 0 && face->style_name && face->family_name) { 108 char *full_name, *unique_name; 109 BDF_PropertyRec prop; 110 int i; 111 if(strcmp(face->style_name, "Regular") == 0) 112 full_name = sprintf_alloc("%s", face->family_name); 113 else 114 full_name = sprintf_alloc("%s %s", 115 face->family_name, face->style_name); 116 117 /* The unique name doesn't actually need to be globally 118 unique; it only needs to be unique among all installed fonts on a 119 Windows system. We don't bother getting it quite right. */ 120 if(face->num_fixed_sizes <= 0) 121 unique_name = sprintf_alloc("%s "XVENDORNAMESHORT" bitmap", 122 full_name); 123 else if(face->available_sizes[0].width == 124 face->available_sizes[0].height) 125 unique_name = sprintf_alloc("%s "XVENDORNAMESHORT 126 " bitmap size %d", 127 full_name, 128 face->available_sizes[0].height); 129 else 130 unique_name = sprintf_alloc("%s "XVENDORNAMESHORT 131 " bitmap size %dx%d", 132 full_name, 133 face->available_sizes[0].width, 134 face->available_sizes[0].height); 135 136 font->names = malloc(10 * sizeof(FontNameEntryRec)); 137 if(font->names == NULL) { 138 fprintf(stderr, "Couldn't allocate names.\n"); 139 return -1; 140 } 141 i = 0; 142 143 rc = FT_Get_BDF_Property(face, "COPYRIGHT", &prop); 144 if(rc == 0 && prop.type == BDF_PROPERTY_TYPE_ATOM) { 145 font->names[i].nid = 0; 146 font->names[i].size = 2 * strlen(prop.u.atom); 147 font->names[i].value = makeUTF16((char*)prop.u.atom); 148 i++; 149 } 150 151 font->names[i].nid = 1; 152 font->names[i].size = 2 * strlen(face->family_name); 153 font->names[i].value = makeUTF16(face->family_name); 154 i++; 155 156 font->names[i].nid = 2; 157 font->names[i].size = 2 * strlen(face->style_name); 158 font->names[i].value = makeUTF16(face->style_name); 159 i++; 160 161 font->names[i].nid = 3; 162 font->names[i].size = 2 * strlen(unique_name); 163 font->names[i].value = makeUTF16(unique_name); 164 i++; 165 166 font->names[i].nid = 4; 167 font->names[i].size = 2 * strlen(full_name); 168 font->names[i].value = makeUTF16(full_name); 169 i++; 170 171 font->names[i].nid = 5; 172 font->names[i].size = 2 * strlen("Version 0.0"); 173 font->names[i].value = makeUTF16("Version 0.0"); 174 i++; 175 176 rc = FT_Get_BDF_Property(face, "FOUNDRY", &prop); 177 if(rc == 0 && prop.type == BDF_PROPERTY_TYPE_ATOM) { 178 font->names[i].nid = 8; 179 font->names[i].size = 2 * strlen(prop.u.atom); 180 font->names[i].value = makeUTF16((char*)prop.u.atom); 181 i++; 182 } 183 184 font->names[i].nid = 10; 185 font->names[i].size = 2 * strlen(XVENDORNAMESHORT 186 " converted bitmap font"); 187 font->names[i].value = makeUTF16(XVENDORNAMESHORT 188 "X converted bitmap font"); 189 i++; 190#ifdef __VENDORWEBSUPPORT__ 191 font->names[i].nid = 11; 192 font->names[i].size = 2 * strlen(__VENDORWEBSUPPORT__); 193 font->names[i].value = makeUTF16(__VENDORWEBSUPPORT__); 194 i++; 195#endif 196 font->numNames = i; 197 198 font->flags = faceFlags(face) | (symbol ? FACE_SYMBOL : 0); 199 font->weight = faceWeight(face); 200 font->width = faceWidth(face); 201 font->foundry = faceFoundry(face); 202 font->italicAngle = faceItalicAngle(face); 203 204 rc = FT_Get_BDF_Property(face, "UNDERLINE_POSITION", &prop); 205 if(rc == 0 && prop.type == BDF_PROPERTY_TYPE_INTEGER) 206 font->underlinePosition = 207 (double)prop.u.integer / face->available_sizes[0].height * 208 TWO_SIXTEENTH; 209 else 210 font->underlinePosition = 211 - 1.5 / face->available_sizes[0].height * TWO_SIXTEENTH; 212 213 rc = FT_Get_BDF_Property(face, "UNDERLINE_THICKNESS", &prop); 214 if(rc == 0 && prop.type == BDF_PROPERTY_TYPE_INTEGER) 215 font->underlineThickness = 216 (double)prop.u.integer / face->available_sizes[0].height * 217 TWO_SIXTEENTH; 218 else 219 font->underlineThickness = 220 1.0 / face->available_sizes[0].height * TWO_SIXTEENTH; 221 } 222 223 if(face->num_fixed_sizes == 0) { 224 fprintf(stderr, "No bitmaps in face.\n"); 225 return -1; 226 } 227 228 if(!symbol && !mapping) 229 rc = FT_Select_Charmap(face, ft_encoding_unicode); 230 else 231 rc = FT_Select_Charmap(face, ft_encoding_none); 232 if(rc != 0) { 233 fprintf(stderr, "Couldn't select character map: %x.\n", rc); 234 return -1; 235 } 236 237 for(int i = 0; i < face->num_fixed_sizes; i++) { 238 if(verbose_flag) 239 fprintf(stderr, "size %d: %dx%d\n", 240 i, 241 (int)(face->available_sizes[i].x_ppem >> 6), 242 (int)(face->available_sizes[i].y_ppem >> 6)); 243 244 rc = FT_Set_Pixel_Sizes(face, 245 face->available_sizes[i].x_ppem >> 6, 246 face->available_sizes[i].y_ppem >> 6); 247 if(rc != 0) { 248 fprintf(stderr, "Couldn't set size.\n"); 249 return -1; 250 } 251 252 strike = makeStrike(font, 253 face->available_sizes[i].x_ppem >> 6, 254 face->available_sizes[i].y_ppem >> 6); 255 if(strike == NULL) { 256 fprintf(stderr, "Couldn't allocate strike.\n"); 257 return -1; 258 } 259 260 for(j = 0; j < FONT_CODES; j++) { 261 if(mapping) 262 k = reverse->reverse(j, reverse->data); 263 else 264 k = j; 265 if(k <= 0 && j != 0) 266 continue; 267 index = FT_Get_Char_Index(face, k); 268 if(j != 0 && index == 0) 269 continue; 270 rc = FT_Load_Glyph(face, index, 271 FT_LOAD_RENDER | FT_LOAD_MONOCHROME); 272 if(rc != 0) { 273 fprintf(stderr, "Couldn't load glyph for U+%04X (%d)\n", 274 j, index); 275 continue; 276 } 277 bitmap = makeBitmap(strike, j, 278 FT_Pos_UP(face->glyph->metrics.horiAdvance), 279 FT_Pos_DOWN(face->glyph->metrics.horiBearingX), 280 FT_Pos_DOWN(face->glyph->metrics.horiBearingY), 281 face->glyph->bitmap.width, 282 face->glyph->bitmap.rows, 283 face->glyph->bitmap.pitch, 284 face->glyph->bitmap.buffer, 285 crop_flag); 286 287 if(bitmap == NULL) { 288 fprintf(stderr, "Couldn't create bitmap.\n"); 289 return -1; 290 } 291 } 292 } 293 294 FT_Done_Face(face); 295 296 j = 0; 297 for(int i = 0; i < FONT_CODES; i++) { 298 int found = 0; 299 strike = font->strikes; 300 while(strike) { 301 bitmap = STRIKE_BITMAP(strike, i); 302 if(bitmap) { 303 bitmap->index = j; 304 found = 1; 305 } else { 306 if(i == 0) { 307 fprintf(stderr, 308 "Warning: no bitmap for the undefined glyph.\n"); 309 found = 1; 310 } 311 } 312 strike = strike->next; 313 } 314 if(found) 315 j++; 316 } 317 return 0; 318} 319