summaryrefslogtreecommitdiff
path: root/read.c
diff options
context:
space:
mode:
Diffstat (limited to 'read.c')
-rw-r--r--read.c310
1 files changed, 310 insertions, 0 deletions
diff --git a/read.c b/read.c
new file mode 100644
index 0000000..07d2f2a
--- /dev/null
+++ b/read.c
@@ -0,0 +1,310 @@
+/*
+Copyright (c) 2002 by Juliusz Chroboczek
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/
+/* $XFree86: xc/programs/fonttosfnt/read.c,v 1.4 2003/11/21 05:22:09 dawes Exp $ */
+
+#include <stdio.h>
+
+#include <ft2build.h>
+#include FT_FREETYPE_H
+#include FT_BDF_H
+#include "fonttosfnt.h"
+#include "fontenc.h"
+
+#define FLOOR2(x, y) ((x) >= 0 ? (x) / (y) : -(((-(x)) + (y) - 1) / (y)))
+#define CEIL2(x, y) (FLOOR2((x) + (y) - 1, (y)))
+#define FT_Pos_DOWN(x) (FLOOR2((x),64))
+#define FT_Pos_UP(x) (CEIL2((x), 64))
+
+static int ft_inited = 0;
+static FT_Library ft_library;
+
+static int
+FT_Ensure_Inited()
+{
+ int rc;
+ if(ft_inited)
+ return 0;
+
+ rc = FT_Init_FreeType(&ft_library);
+ if(rc != 0)
+ return rc;
+
+ ft_inited = 1;
+ return 0;
+}
+
+int
+readFile(char *filename, FontPtr font)
+{
+ int i, j, k, index;
+ int rc;
+ FT_Face face;
+ StrikePtr strike;
+ BitmapPtr bitmap;
+ int symbol = 0;
+ char *encoding_name = NULL;
+ FontMapPtr mapping = NULL;
+ FontMapReversePtr reverse = NULL;
+
+
+ rc = FT_Ensure_Inited();
+ if(rc != 0)
+ return rc;
+
+ rc = FT_New_Face(ft_library, filename, 0, &face);
+ if(rc != 0) {
+ fprintf(stderr, "Couldn't open face %s.\n", filename);
+ return -1;
+ }
+
+ encoding_name = faceEncoding(face);
+ if(encoding_name == NULL) {
+ symbol = 1;
+ } else if(strcasecmp(encoding_name, "iso10646-1") != 0) {
+ if(reencode_flag)
+ mapping = FontEncMapFind(encoding_name,
+ FONT_ENCODING_UNICODE, 0, 0, NULL);
+ if(mapping == NULL) {
+ symbol = 1;
+ } else {
+ reverse = FontMapReverse(mapping);
+ if(reverse == NULL) {
+ fprintf(stderr, "Couldn't reverse mapping.\n");
+ return -1;
+ }
+ }
+ }
+
+ if(verbose_flag) {
+ fprintf(stderr, "%s %s %s: %d sizes%s\n",
+ filename, face->family_name, face->style_name,
+ face->num_fixed_sizes,
+ symbol ? " (symbol)" : "");
+ }
+
+ if(font->numNames == 0 && face->style_name && face->family_name) {
+ char *full_name, *unique_name;
+ BDF_PropertyRec prop;
+ int rc, i;
+ if(strcmp(face->style_name, "Regular") == 0)
+ full_name = sprintf_reliable("%s", face->family_name);
+ else
+ full_name = sprintf_reliable("%s %s",
+ face->family_name, face->style_name);
+
+ /* The unique name doesn't actually need to be globally
+ unique; it only needs to be unique among all installed fonts on a
+ Windows system. We don't bother getting it quite right. */
+ if(face->num_fixed_sizes <= 0)
+ unique_name = sprintf_reliable("%s XFree86 bitmap", full_name);
+ else if(face->available_sizes[0].width ==
+ face->available_sizes[0].height)
+ unique_name = sprintf_reliable("%s XFree86 bitmap size %d",
+ full_name,
+ face->available_sizes[0].height);
+ else
+ unique_name = sprintf_reliable("%s XFree86 bitmap size %dx%d",
+ full_name,
+ face->available_sizes[0].width,
+ face->available_sizes[0].height);
+
+ font->names = malloc(10 * sizeof(FontNameEntryRec));
+ if(font->names == NULL) {
+ fprintf(stderr, "Couldn't allocate names.\n");
+ return -1;
+ }
+ i = 0;
+
+ rc = FT_Get_BDF_Property(face, "COPYRIGHT", &prop);
+ if(rc == 0 && prop.type == BDF_PROPERTY_TYPE_ATOM) {
+ font->names[i].nid = 0;
+ font->names[i].size = 2 * strlen(prop.u.atom);
+ font->names[i].value = makeUTF16((char*)prop.u.atom);
+ i++;
+ }
+
+ font->names[i].nid = 1;
+ font->names[i].size = 2 * strlen(face->family_name);
+ font->names[i].value = makeUTF16(face->family_name);
+ i++;
+
+ font->names[i].nid = 2;
+ font->names[i].size = 2 * strlen(face->style_name);
+ font->names[i].value = makeUTF16(face->style_name);
+ i++;
+
+ font->names[i].nid = 3;
+ font->names[i].size = 2 * strlen(unique_name);
+ font->names[i].value = makeUTF16(unique_name);
+ i++;
+
+ font->names[i].nid = 4;
+ font->names[i].size = 2 * strlen(full_name);
+ font->names[i].value = makeUTF16(full_name);
+ i++;
+
+ font->names[i].nid = 5;
+ font->names[i].size = 2 * strlen("Version 0.0");
+ font->names[i].value = makeUTF16("Version 0.0");
+ i++;
+
+ rc = FT_Get_BDF_Property(face, "FOUNDRY", &prop);
+ if(rc == 0 && prop.type == BDF_PROPERTY_TYPE_ATOM) {
+ font->names[i].nid = 8;
+ font->names[i].size = 2 * strlen(prop.u.atom);
+ font->names[i].value = makeUTF16((char*)prop.u.atom);
+ i++;
+ }
+
+ font->names[i].nid = 10;
+ font->names[i].size = 2 * strlen("XFree86 converted bitmap font");
+ font->names[i].value = makeUTF16("XFree86 converted bitmap font");
+ i++;
+
+ font->names[i].nid = 11;
+ font->names[i].size = 2 * strlen("http://www.xfree86.org");
+ font->names[i].value = makeUTF16("http://www.xfree86.org");
+ i++;
+
+ font->numNames = i;
+
+ font->flags = faceFlags(face) | (symbol ? FACE_SYMBOL : 0);
+ font->weight = faceWeight(face);
+ font->width = faceWidth(face);
+ font->foundry = faceFoundry(face);
+ font->italicAngle = faceItalicAngle(face);
+
+ rc = FT_Get_BDF_Property(face, "UNDERLINE_POSITION", &prop);
+ if(rc == 0 && prop.type == BDF_PROPERTY_TYPE_INTEGER)
+ font->underlinePosition =
+ (double)prop.u.integer / face->available_sizes[0].height *
+ TWO_SIXTEENTH;
+ else
+ font->underlinePosition =
+ - 1.5 / face->available_sizes[0].height * TWO_SIXTEENTH;
+
+ rc = FT_Get_BDF_Property(face, "UNDERLINE_THICKNESS", &prop);
+ if(rc == 0 && prop.type == BDF_PROPERTY_TYPE_INTEGER)
+ font->underlineThickness =
+ (double)prop.u.integer / face->available_sizes[0].height *
+ TWO_SIXTEENTH;
+ else
+ font->underlineThickness =
+ 1.0 / face->available_sizes[0].height * TWO_SIXTEENTH;
+ }
+
+ if(face->num_fixed_sizes == 0) {
+ fprintf(stderr, "No bitmaps in face.\n");
+ return -1;
+ }
+
+ if(!symbol && !mapping)
+ rc = FT_Select_Charmap(face, ft_encoding_unicode);
+ else
+ rc = FT_Select_Charmap(face, ft_encoding_none);
+ if(rc != 0) {
+ fprintf(stderr, "Couldn't select character map: %x.\n", rc);
+ return -1;
+ }
+
+ for(i = 0; i < face->num_fixed_sizes; i++) {
+ if(verbose_flag)
+ fprintf(stderr, "size %d: %dx%d\n",
+ i,
+ face->available_sizes[i].width,
+ face->available_sizes[i].height);
+
+ rc = FT_Set_Pixel_Sizes(face,
+ face->available_sizes[i].width,
+ face->available_sizes[i].height);
+ if(rc != 0) {
+ fprintf(stderr, "Couldn't set size.\n");
+ return -1;
+ }
+
+ strike = makeStrike(font,
+ face->available_sizes[i].width,
+ face->available_sizes[i].height);
+ if(strike == NULL) {
+ fprintf(stderr, "Couldn't allocate strike.\n");
+ return -1;
+ }
+
+ for(j = 0; j < FONT_CODES; j++) {
+ if(mapping)
+ k = reverse->reverse(j, reverse->data);
+ else
+ k = j;
+ if(k <= 0 && j != 0)
+ continue;
+ index = FT_Get_Char_Index(face, k);
+ if(j != 0 && index == 0)
+ continue;
+ rc = FT_Load_Glyph(face, index,
+ FT_LOAD_RENDER | FT_LOAD_MONOCHROME);
+ if(rc != 0) {
+ fprintf(stderr, "Couldn't load glyph for U+%04X (%d)\n",
+ j, index);
+ continue;
+ }
+ bitmap = makeBitmap(strike, j,
+ FT_Pos_UP(face->glyph->metrics.horiAdvance),
+ FT_Pos_DOWN(face->glyph->metrics.horiBearingX),
+ FT_Pos_DOWN(face->glyph->metrics.horiBearingY),
+ face->glyph->bitmap.width,
+ face->glyph->bitmap.rows,
+ face->glyph->bitmap.pitch,
+ face->glyph->bitmap.buffer,
+ crop_flag);
+
+ if(bitmap == NULL) {
+ fprintf(stderr, "Couldn't create bitmap.\n");
+ return -1;
+ }
+ }
+ }
+
+ FT_Done_Face(face);
+
+ j = 0;
+ for(i = 0; i < FONT_CODES; i++) {
+ int found = 0;
+ strike = font->strikes;
+ while(strike) {
+ bitmap = STRIKE_BITMAP(strike, i);
+ if(bitmap) {
+ bitmap->index = j;
+ found = 1;
+ } else {
+ if(i == 0) {
+ fprintf(stderr,
+ "Warning: no bitmap for the undefined glyph.\n");
+ found = 1;
+ }
+ }
+ strike = strike->next;
+ }
+ if(found)
+ j++;
+ }
+ return 0;
+}