read.c revision 6ef05171
143f32c10Smrg/* $XdotOrg: xc/programs/fonttosfnt/read.c,v 1.2 2004/04/23 19:54:32 eich Exp $ */ 243f32c10Smrg/* 343f32c10SmrgCopyright (c) 2002 by Juliusz Chroboczek 443f32c10Smrg 543f32c10SmrgPermission is hereby granted, free of charge, to any person obtaining a copy 643f32c10Smrgof this software and associated documentation files (the "Software"), to deal 743f32c10Smrgin the Software without restriction, including without limitation the rights 843f32c10Smrgto use, copy, modify, merge, publish, distribute, sublicense, and/or sell 943f32c10Smrgcopies of the Software, and to permit persons to whom the Software is 1043f32c10Smrgfurnished to do so, subject to the following conditions: 1143f32c10Smrg 1243f32c10SmrgThe above copyright notice and this permission notice shall be included in 1343f32c10Smrgall copies or substantial portions of the Software. 1443f32c10Smrg 1543f32c10SmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 1643f32c10SmrgIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 1743f32c10SmrgFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 1843f32c10SmrgAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 1943f32c10SmrgLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 2043f32c10SmrgOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 2143f32c10SmrgTHE SOFTWARE. 2243f32c10Smrg*/ 2343f32c10Smrg/* $XdotOrg: xc/programs/fonttosfnt/read.c,v 1.2 2004/04/23 19:54:32 eich Exp $ */ 2443f32c10Smrg/* $XFree86: xc/programs/fonttosfnt/read.c,v 1.5 2003/12/19 02:05:39 dawes Exp $ */ 2543f32c10Smrg 2643f32c10Smrg#include <stdio.h> 2743f32c10Smrg 2843f32c10Smrg#include <ft2build.h> 2943f32c10Smrg#include FT_FREETYPE_H 3043f32c10Smrg#include FT_BDF_H 3143f32c10Smrg#include "X11/Xos.h" 3243f32c10Smrg#include "fonttosfnt.h" 3343f32c10Smrg#include "X11/fonts/fontenc.h" 3443f32c10Smrg 3543f32c10Smrg#define FLOOR2(x, y) ((x) >= 0 ? (x) / (y) : -(((-(x)) + (y) - 1) / (y))) 3643f32c10Smrg#define CEIL2(x, y) (FLOOR2((x) + (y) - 1, (y))) 3743f32c10Smrg#define FT_Pos_DOWN(x) (FLOOR2((x),64)) 3843f32c10Smrg#define FT_Pos_UP(x) (CEIL2((x), 64)) 3943f32c10Smrg 4043f32c10Smrgstatic int ft_inited = 0; 4143f32c10Smrgstatic FT_Library ft_library; 4243f32c10Smrg 4343f32c10Smrgstatic int 4443f32c10SmrgFT_Ensure_Inited(void) 4543f32c10Smrg{ 4643f32c10Smrg int rc; 4743f32c10Smrg if(ft_inited) 4843f32c10Smrg return 0; 4943f32c10Smrg 5043f32c10Smrg rc = FT_Init_FreeType(&ft_library); 5143f32c10Smrg if(rc != 0) 5243f32c10Smrg return rc; 5343f32c10Smrg 5443f32c10Smrg ft_inited = 1; 5543f32c10Smrg return 0; 5643f32c10Smrg} 5743f32c10Smrg 5843f32c10Smrgint 5943f32c10SmrgreadFile(char *filename, FontPtr font) 6043f32c10Smrg{ 616ef05171Smrg int j, k, index; 6243f32c10Smrg int rc; 6343f32c10Smrg FT_Face face; 6443f32c10Smrg StrikePtr strike; 6543f32c10Smrg BitmapPtr bitmap; 6643f32c10Smrg int symbol = 0; 6743f32c10Smrg char *encoding_name = NULL; 6843f32c10Smrg FontMapPtr mapping = NULL; 6943f32c10Smrg FontMapReversePtr reverse = NULL; 7043f32c10Smrg 7143f32c10Smrg 7243f32c10Smrg rc = FT_Ensure_Inited(); 7343f32c10Smrg if(rc != 0) 7443f32c10Smrg return rc; 7543f32c10Smrg 7643f32c10Smrg rc = FT_New_Face(ft_library, filename, 0, &face); 7743f32c10Smrg if(rc != 0) { 7843f32c10Smrg fprintf(stderr, "Couldn't open face %s.\n", filename); 7943f32c10Smrg return -1; 8043f32c10Smrg } 8143f32c10Smrg 8243f32c10Smrg encoding_name = faceEncoding(face); 8343f32c10Smrg if(encoding_name == NULL) { 8443f32c10Smrg symbol = 1; 8543f32c10Smrg } else if(strcasecmp(encoding_name, "iso10646-1") != 0) { 8643f32c10Smrg if(reencode_flag) 8743f32c10Smrg mapping = FontEncMapFind(encoding_name, 8843f32c10Smrg FONT_ENCODING_UNICODE, 0, 0, NULL); 8943f32c10Smrg if(mapping == NULL) { 9043f32c10Smrg symbol = 1; 9143f32c10Smrg } else { 9243f32c10Smrg reverse = FontMapReverse(mapping); 9343f32c10Smrg if(reverse == NULL) { 9443f32c10Smrg fprintf(stderr, "Couldn't reverse mapping.\n"); 9543f32c10Smrg return -1; 9643f32c10Smrg } 9743f32c10Smrg } 9843f32c10Smrg } 9943f32c10Smrg 10043f32c10Smrg if(verbose_flag) { 10143f32c10Smrg fprintf(stderr, "%s %s %s: %d sizes%s\n", 10243f32c10Smrg filename, face->family_name, face->style_name, 10343f32c10Smrg face->num_fixed_sizes, 10443f32c10Smrg symbol ? " (symbol)" : ""); 10543f32c10Smrg } 10643f32c10Smrg 10743f32c10Smrg if(font->numNames == 0 && face->style_name && face->family_name) { 10843f32c10Smrg char *full_name, *unique_name; 10943f32c10Smrg BDF_PropertyRec prop; 1106ef05171Smrg int i; 11143f32c10Smrg if(strcmp(face->style_name, "Regular") == 0) 11243f32c10Smrg full_name = sprintf_alloc("%s", face->family_name); 11343f32c10Smrg else 11443f32c10Smrg full_name = sprintf_alloc("%s %s", 11543f32c10Smrg face->family_name, face->style_name); 11643f32c10Smrg 11743f32c10Smrg /* The unique name doesn't actually need to be globally 11843f32c10Smrg unique; it only needs to be unique among all installed fonts on a 11943f32c10Smrg Windows system. We don't bother getting it quite right. */ 12043f32c10Smrg if(face->num_fixed_sizes <= 0) 12143f32c10Smrg unique_name = sprintf_alloc("%s "XVENDORNAMESHORT" bitmap", 12243f32c10Smrg full_name); 12343f32c10Smrg else if(face->available_sizes[0].width == 12443f32c10Smrg face->available_sizes[0].height) 12543f32c10Smrg unique_name = sprintf_alloc("%s "XVENDORNAMESHORT 12643f32c10Smrg " bitmap size %d", 12743f32c10Smrg full_name, 12843f32c10Smrg face->available_sizes[0].height); 12943f32c10Smrg else 13043f32c10Smrg unique_name = sprintf_alloc("%s "XVENDORNAMESHORT 13143f32c10Smrg " bitmap size %dx%d", 13243f32c10Smrg full_name, 13343f32c10Smrg face->available_sizes[0].width, 13443f32c10Smrg face->available_sizes[0].height); 13543f32c10Smrg 13643f32c10Smrg font->names = malloc(10 * sizeof(FontNameEntryRec)); 13743f32c10Smrg if(font->names == NULL) { 13843f32c10Smrg fprintf(stderr, "Couldn't allocate names.\n"); 13943f32c10Smrg return -1; 14043f32c10Smrg } 14143f32c10Smrg i = 0; 14243f32c10Smrg 14343f32c10Smrg rc = FT_Get_BDF_Property(face, "COPYRIGHT", &prop); 14443f32c10Smrg if(rc == 0 && prop.type == BDF_PROPERTY_TYPE_ATOM) { 14543f32c10Smrg font->names[i].nid = 0; 14643f32c10Smrg font->names[i].size = 2 * strlen(prop.u.atom); 14743f32c10Smrg font->names[i].value = makeUTF16((char*)prop.u.atom); 14843f32c10Smrg i++; 14943f32c10Smrg } 15043f32c10Smrg 15143f32c10Smrg font->names[i].nid = 1; 15243f32c10Smrg font->names[i].size = 2 * strlen(face->family_name); 15343f32c10Smrg font->names[i].value = makeUTF16(face->family_name); 15443f32c10Smrg i++; 15543f32c10Smrg 15643f32c10Smrg font->names[i].nid = 2; 15743f32c10Smrg font->names[i].size = 2 * strlen(face->style_name); 15843f32c10Smrg font->names[i].value = makeUTF16(face->style_name); 15943f32c10Smrg i++; 16043f32c10Smrg 16143f32c10Smrg font->names[i].nid = 3; 16243f32c10Smrg font->names[i].size = 2 * strlen(unique_name); 16343f32c10Smrg font->names[i].value = makeUTF16(unique_name); 16443f32c10Smrg i++; 16543f32c10Smrg 16643f32c10Smrg font->names[i].nid = 4; 16743f32c10Smrg font->names[i].size = 2 * strlen(full_name); 16843f32c10Smrg font->names[i].value = makeUTF16(full_name); 16943f32c10Smrg i++; 17043f32c10Smrg 17143f32c10Smrg font->names[i].nid = 5; 17243f32c10Smrg font->names[i].size = 2 * strlen("Version 0.0"); 17343f32c10Smrg font->names[i].value = makeUTF16("Version 0.0"); 17443f32c10Smrg i++; 17543f32c10Smrg 17643f32c10Smrg rc = FT_Get_BDF_Property(face, "FOUNDRY", &prop); 17743f32c10Smrg if(rc == 0 && prop.type == BDF_PROPERTY_TYPE_ATOM) { 17843f32c10Smrg font->names[i].nid = 8; 17943f32c10Smrg font->names[i].size = 2 * strlen(prop.u.atom); 18043f32c10Smrg font->names[i].value = makeUTF16((char*)prop.u.atom); 18143f32c10Smrg i++; 18243f32c10Smrg } 18343f32c10Smrg 18443f32c10Smrg font->names[i].nid = 10; 18543f32c10Smrg font->names[i].size = 2 * strlen(XVENDORNAMESHORT 18643f32c10Smrg " converted bitmap font"); 18743f32c10Smrg font->names[i].value = makeUTF16(XVENDORNAMESHORT 18843f32c10Smrg "X converted bitmap font"); 18943f32c10Smrg i++; 19043f32c10Smrg#ifdef __VENDORWEBSUPPORT__ 19143f32c10Smrg font->names[i].nid = 11; 19243f32c10Smrg font->names[i].size = 2 * strlen(__VENDORWEBSUPPORT__); 19343f32c10Smrg font->names[i].value = makeUTF16(__VENDORWEBSUPPORT__); 19443f32c10Smrg i++; 19543f32c10Smrg#endif 19643f32c10Smrg font->numNames = i; 19743f32c10Smrg 19843f32c10Smrg font->flags = faceFlags(face) | (symbol ? FACE_SYMBOL : 0); 19943f32c10Smrg font->weight = faceWeight(face); 20043f32c10Smrg font->width = faceWidth(face); 20143f32c10Smrg font->foundry = faceFoundry(face); 20243f32c10Smrg font->italicAngle = faceItalicAngle(face); 20343f32c10Smrg 20443f32c10Smrg rc = FT_Get_BDF_Property(face, "UNDERLINE_POSITION", &prop); 20543f32c10Smrg if(rc == 0 && prop.type == BDF_PROPERTY_TYPE_INTEGER) 20643f32c10Smrg font->underlinePosition = 20743f32c10Smrg (double)prop.u.integer / face->available_sizes[0].height * 20843f32c10Smrg TWO_SIXTEENTH; 20943f32c10Smrg else 21043f32c10Smrg font->underlinePosition = 21143f32c10Smrg - 1.5 / face->available_sizes[0].height * TWO_SIXTEENTH; 21243f32c10Smrg 21343f32c10Smrg rc = FT_Get_BDF_Property(face, "UNDERLINE_THICKNESS", &prop); 21443f32c10Smrg if(rc == 0 && prop.type == BDF_PROPERTY_TYPE_INTEGER) 21543f32c10Smrg font->underlineThickness = 21643f32c10Smrg (double)prop.u.integer / face->available_sizes[0].height * 21743f32c10Smrg TWO_SIXTEENTH; 21843f32c10Smrg else 21943f32c10Smrg font->underlineThickness = 22043f32c10Smrg 1.0 / face->available_sizes[0].height * TWO_SIXTEENTH; 22143f32c10Smrg } 22243f32c10Smrg 22343f32c10Smrg if(face->num_fixed_sizes == 0) { 22443f32c10Smrg fprintf(stderr, "No bitmaps in face.\n"); 22543f32c10Smrg return -1; 22643f32c10Smrg } 22743f32c10Smrg 22843f32c10Smrg if(!symbol && !mapping) 22943f32c10Smrg rc = FT_Select_Charmap(face, ft_encoding_unicode); 23043f32c10Smrg else 23143f32c10Smrg rc = FT_Select_Charmap(face, ft_encoding_none); 23243f32c10Smrg if(rc != 0) { 23343f32c10Smrg fprintf(stderr, "Couldn't select character map: %x.\n", rc); 23443f32c10Smrg return -1; 23543f32c10Smrg } 23643f32c10Smrg 2376ef05171Smrg for(int i = 0; i < face->num_fixed_sizes; i++) { 23843f32c10Smrg if(verbose_flag) 23943f32c10Smrg fprintf(stderr, "size %d: %dx%d\n", 24043f32c10Smrg i, 2416ef05171Smrg (int)(face->available_sizes[i].x_ppem >> 6), 2426ef05171Smrg (int)(face->available_sizes[i].y_ppem >> 6)); 24343f32c10Smrg 24443f32c10Smrg rc = FT_Set_Pixel_Sizes(face, 24543f32c10Smrg face->available_sizes[i].x_ppem >> 6, 24643f32c10Smrg face->available_sizes[i].y_ppem >> 6); 24743f32c10Smrg if(rc != 0) { 24843f32c10Smrg fprintf(stderr, "Couldn't set size.\n"); 24943f32c10Smrg return -1; 25043f32c10Smrg } 25143f32c10Smrg 25243f32c10Smrg strike = makeStrike(font, 25343f32c10Smrg face->available_sizes[i].x_ppem >> 6, 25443f32c10Smrg face->available_sizes[i].y_ppem >> 6); 25543f32c10Smrg if(strike == NULL) { 25643f32c10Smrg fprintf(stderr, "Couldn't allocate strike.\n"); 25743f32c10Smrg return -1; 25843f32c10Smrg } 25943f32c10Smrg 26043f32c10Smrg for(j = 0; j < FONT_CODES; j++) { 26143f32c10Smrg if(mapping) 26243f32c10Smrg k = reverse->reverse(j, reverse->data); 26343f32c10Smrg else 26443f32c10Smrg k = j; 26543f32c10Smrg if(k <= 0 && j != 0) 26643f32c10Smrg continue; 26743f32c10Smrg index = FT_Get_Char_Index(face, k); 26843f32c10Smrg if(j != 0 && index == 0) 26943f32c10Smrg continue; 27043f32c10Smrg rc = FT_Load_Glyph(face, index, 27143f32c10Smrg FT_LOAD_RENDER | FT_LOAD_MONOCHROME); 27243f32c10Smrg if(rc != 0) { 27343f32c10Smrg fprintf(stderr, "Couldn't load glyph for U+%04X (%d)\n", 27443f32c10Smrg j, index); 27543f32c10Smrg continue; 27643f32c10Smrg } 27743f32c10Smrg bitmap = makeBitmap(strike, j, 27843f32c10Smrg FT_Pos_UP(face->glyph->metrics.horiAdvance), 27943f32c10Smrg FT_Pos_DOWN(face->glyph->metrics.horiBearingX), 28043f32c10Smrg FT_Pos_DOWN(face->glyph->metrics.horiBearingY), 28143f32c10Smrg face->glyph->bitmap.width, 28243f32c10Smrg face->glyph->bitmap.rows, 28343f32c10Smrg face->glyph->bitmap.pitch, 28443f32c10Smrg face->glyph->bitmap.buffer, 28543f32c10Smrg crop_flag); 28643f32c10Smrg 28743f32c10Smrg if(bitmap == NULL) { 28843f32c10Smrg fprintf(stderr, "Couldn't create bitmap.\n"); 28943f32c10Smrg return -1; 29043f32c10Smrg } 29143f32c10Smrg } 29243f32c10Smrg } 29343f32c10Smrg 29443f32c10Smrg FT_Done_Face(face); 29543f32c10Smrg 29643f32c10Smrg j = 0; 2976ef05171Smrg for(int i = 0; i < FONT_CODES; i++) { 29843f32c10Smrg int found = 0; 29943f32c10Smrg strike = font->strikes; 30043f32c10Smrg while(strike) { 30143f32c10Smrg bitmap = STRIKE_BITMAP(strike, i); 30243f32c10Smrg if(bitmap) { 30343f32c10Smrg bitmap->index = j; 30443f32c10Smrg found = 1; 30543f32c10Smrg } else { 30643f32c10Smrg if(i == 0) { 30743f32c10Smrg fprintf(stderr, 30843f32c10Smrg "Warning: no bitmap for the undefined glyph.\n"); 30943f32c10Smrg found = 1; 31043f32c10Smrg } 31143f32c10Smrg } 31243f32c10Smrg strike = strike->next; 31343f32c10Smrg } 31443f32c10Smrg if(found) 31543f32c10Smrg j++; 31643f32c10Smrg } 31743f32c10Smrg return 0; 31843f32c10Smrg} 319