moved from ../xpdf/
[swftools.git] / lib / gfxfont.c
index ee4b9cb..45a44ca 100644 (file)
@@ -136,7 +136,7 @@ static void glyph_clear(gfxglyph_t*g)
 
 static int errorno = 0;
 
-gfxfont_t* gfxfont_load(char*filename, double quality)
+gfxfont_t* gfxfont_load(char*id, char*filename, double quality)
 {
     FT_Face face;
     FT_Error error;
@@ -152,6 +152,7 @@ gfxfont_t* gfxfont_load(char*filename, double quality)
     int charmap = -1;
     int isunicode = 1;
     int has_had_errors = 0;
+    int num_names = 0;
 
     if(ftlibrary == 0) {
        if(FT_Init_FreeType(&ftlibrary)) {
@@ -163,7 +164,7 @@ gfxfont_t* gfxfont_load(char*filename, double quality)
     FT_Set_Pixel_Sizes (face, 16*loadfont_scale, 16*loadfont_scale);
 
     if(error) {
-       fprintf(stderr, "Couldn't load file %s- not a TTF file?\n", filename);
+       fprintf(stderr, "Couldn't load file %s- not a TTF file? (error=%02x)\n", filename, error);
        return 0;
     }
     if(face->num_glyphs <= 0) {
@@ -178,6 +179,7 @@ gfxfont_t* gfxfont_load(char*filename, double quality)
     //font->leading = font->layout->ascent + font->layout->descent;
     //font->encoding = FONT_ENCODING_UNICODE;
     font->max_unicode = 0;
+    font->id = strdup(id);
     
     font->glyphs = rfx_calloc(face->num_glyphs*sizeof(gfxglyph_t));
     glyph2unicode = rfx_calloc(face->num_glyphs*sizeof(int));
@@ -210,12 +212,13 @@ gfxfont_t* gfxfont_load(char*filename, double quality)
           the encoding is no longer unicode. 
           TODO: find a way to convert the encoding to unicode
         */
-       if(font->max_unicode == 0 && charmap < face->num_charmaps - 1) {
+       if(font->max_unicode == 0 && charmap < face->num_charmaps-1 && 
+               face->charmaps[charmap+1]->encoding != 0x41444243 /* custom */)
+               {
            charmap++;
            FT_Set_Charmap(face, face->charmaps[charmap]);
-           //font->encoding = 0;//anything but unicode FIXME
            isunicode = 0;
-       } else 
+       } else
            break;
     }
 
@@ -243,6 +246,18 @@ gfxfont_t* gfxfont_load(char*filename, double quality)
 
     font->num_glyphs = 0;
 
+
+    for(t=0; t < face->num_glyphs; t++) {
+       if(FT_HAS_GLYPH_NAMES(face)) {
+           char name[128];
+           error = FT_Get_Glyph_Name(face, t, name, 127);
+           if(!error && name[0] && !strstr(name, "notdef")) {
+               num_names++;
+           }
+       }
+    }
+
+
     for(t=0; t < face->num_glyphs; t++) {
        FT_Glyph glyph;
        FT_BBox bbox;
@@ -260,7 +275,8 @@ gfxfont_t* gfxfont_load(char*filename, double quality)
        font->glyphs[font->num_glyphs].unicode = glyph2unicode[t];
        font->glyphs[font->num_glyphs].name = 0;
 
-       if(FT_HAS_GLYPH_NAMES(face)) {
+       if(FT_HAS_GLYPH_NAMES(face) && (num_names >= face->num_glyphs/10 || num_names > 2)) {
+           name[0] = 0;
            error = FT_Get_Glyph_Name(face, t, name, 127);
            if(!error && name[0] && !strstr(name, "notdef")) {
                font->glyphs[font->num_glyphs].name = strdup(name);
@@ -280,7 +296,7 @@ gfxfont_t* gfxfont_load(char*filename, double quality)
                    fprintf(stderr, "Warning: glyph %d/%d (unicode %d, name %s) has return code %d\n", t, face->num_glyphs, glyph2unicode[t], name, error);
                else
                    fprintf(stderr, "Warning: glyph %d/%d (unicode %d) has return code %d\n", t, face->num_glyphs, glyph2unicode[t], error);
-               omit = 1;
+               omit = 2;
 
 #if 0
                if(!has_had_errors) {
@@ -303,11 +319,13 @@ gfxfont_t* gfxfont_load(char*filename, double quality)
            error = FT_Get_Glyph(face->glyph, &glyph);
            if(error) {
                fprintf(stderr, "Couldn't get glyph %d/%d, error:%d\n", t, face->num_glyphs, error);
-               omit = 1;
+               omit = 3;
            }
        }
 
        if(!omit) {
+           gfxline_t*l;
+           int ok=0;
            gfxdrawer_target_gfxline(&draw);
            info.draw = &draw;
            info.quality = quality;
@@ -319,16 +337,44 @@ gfxfont_t* gfxfont_load(char*filename, double quality)
                fprintf(stderr, "Couldn't decompose glyph %d\n", t);
                gfxline_free((gfxline_t*)draw.result(&draw));
                FT_Done_Glyph(glyph);
-               omit = 1;
+               omit = 4;
            } else {
-               font->glyphs[font->num_glyphs].advance = glyph->advance.x*20/65536;
+               font->glyphs[font->num_glyphs].advance = (glyph->advance.x*20)/65536;
                font->glyphs[font->num_glyphs].line = (gfxline_t*)draw.result(&draw);
            }
+           l = font->glyphs[font->num_glyphs].line;
+           while(l) {
+               if(l->type != gfx_moveTo) {
+                   ok = 1;
+               }
+               l = l->next;
+           }
+           if(!ok && !name) {
+               gfxline_free(font->glyphs[font->num_glyphs].line);
+               font->glyphs[font->num_glyphs].line = 0;
+               font->glyphs[font->num_glyphs].advance = 0;
+
+               /* Some PDFs created e.g. by InDesign tend to create
+                  fonts with reduced (empty) characters, which still
+                  have unicode indices attached to them.
+                  Remove that information, in order to not confuse
+                  any converter applications.
+                   */
+               font->glyphs[font->num_glyphs].unicode = 0;
+               if(font->glyphs[font->num_glyphs].name) {
+                   free(font->glyphs[font->num_glyphs].name);
+                   font->glyphs[font->num_glyphs].name = 0;
+               }
+               FT_Done_Glyph(glyph);
+               omit = 5;
+           }
        }
 
        if(!omit) {
            FT_Done_Glyph(glyph);
+           font->glyphs[font->num_glyphs].unicode = glyph2unicode[t];
        }
+
        glyph2glyph[t] = font->num_glyphs;
        font->num_glyphs++;
     }
@@ -347,8 +393,8 @@ gfxfont_t* gfxfont_load(char*filename, double quality)
 
     FT_Done_Face(face);
     FT_Done_FreeType(ftlibrary);ftlibrary=0;
-  
-    if(!isunicode && font->num_glyphs>0) {
+    if(!isunicode && font->num_glyphs>0 && font->max_unicode) {
        /* if the encoding isn't unicode, remap the font
           so that the encoding equals the char position, and
           remove the unicode table */