more horizontal refactoring
[swftools.git] / lib / gfxfont.c
index c0cbac2..549e50d 100644 (file)
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
 
 #include <assert.h>
+#include <stdio.h>
+#include <memory.h>
 #include "../config.h"
 #include "gfxdevice.h"
 #include "gfxtools.h"
 #include "gfxfont.h"
 #include "ttf.h"
 #include "mem.h"
+#include "log.h"
 
 static int loadfont_scale = 64;
 static int full_unicode = 1;
@@ -142,7 +145,7 @@ static int errorno = 0;
 
 //#define DEBUG 1
 
-gfxfont_t* gfxfont_load(char*id, char*filename, unsigned int flags, double quality)
+gfxfont_t* gfxfont_load(const char*id, const char*filename, unsigned int flags, double quality)
 {
     FT_Face face;
     FT_Error error;
@@ -491,7 +494,7 @@ gfxfont_t* gfxfont_load(char*id, char*filename, unsigned int flags, double quali
 }
 #else
 
-gfxfont_t* gfxfont_load(char*id, char*filename, unsigned int flags, double quality)
+gfxfont_t* gfxfont_load(const char*id, const char*filename, unsigned int flags, double quality)
 {
     fprintf(stderr, "No freetype support compiled in! Not able to load %s\n", filename);
     return 0;
@@ -556,7 +559,22 @@ void gfxfont_fix_unicode(gfxfont_t*font)
            max = u;
     }
     free(used);
-    
+    if(font->unicode2glyph) {
+       free(font->unicode2glyph);
+    }
+    font->unicode2glyph = 0;
+    font->max_unicode = 0;
+}
+
+void gfxfont_add_unicode2glyph(gfxfont_t*font)
+{ 
+    int t;
+    int max = 0;
+    for(t=0;t<font->num_glyphs;t++) {
+       int u = font->glyphs[t].unicode;
+       if(u > max)
+           max = u;
+    }
     if(!font->unicode2glyph) {
        /* (re)generate unicode2glyph-to-glyph mapping table by reverse mapping
           the glyph unicode2glyph's indexes into the mapping table. For collisions,
@@ -569,6 +587,7 @@ void gfxfont_fix_unicode(gfxfont_t*font)
            int u = font->glyphs[t].unicode;
            if(u>=0) {
                assert(font->unicode2glyph[u]<0); // we took care of duplicates, right?
+               assert(u<font->max_unicode);
                font->unicode2glyph[u] = t;
            }
        }
@@ -591,7 +610,7 @@ void gfxfont_fix_unicode(gfxfont_t*font)
     }
 }
 
-ttf_t* gfxfont_to_ttf(gfxfont_t*font)
+ttf_t* gfxfont_to_ttf(gfxfont_t*font, char eot)
 {
     ttf_t*ttf = ttf_new();
     int num_glyphs = font->num_glyphs;
@@ -663,33 +682,59 @@ ttf_t* gfxfont_to_ttf(gfxfont_t*font)
            }
        }
 
+       if(eot) {
+           dest->bearing = dest->xmin;
+           /* for windows font rendering, make sure coordinates are always 
+              to the right of the origin (and use bearing to shift them "back".)
+              Don't do this for non-windows platforms though because e.g. OS X 
+              ignores bearing. */
+           int xshift=0;
+           if(dest->xmin < 0) {
+               xshift = -dest->xmin;
+               for(s=0;s<count;s++) {
+                   dest->points[s].x += xshift;
+               }
+               dest->xmin += xshift;
+               dest->xmax += xshift;
+           }
+       }
+       dest->advance = src->advance*scale;
+
+       //dest->xmin=0; //TODO: might be necessary for some font engines?
+
        dest->advance = src->advance*scale;
 
        int u = font->glyphs[t].unicode;
-       if(invalid_unicode(u)) {
-           u = 0xe000 + remap_pos++;
-       }
        if(u > max_unicode)
            max_unicode = u;
     }
     ttf->unicode_size = max_unicode+1;
     ttf->unicode = rfx_calloc(sizeof(unicode_t)*ttf->unicode_size);
-    remap_pos=0;
-    for(t=0;t<font->num_glyphs;t++) {
-       gfxglyph_t*src = &font->glyphs[t];
-       int u = font->glyphs[t].unicode;
-       if(invalid_unicode(u)) {
-           u = 0xe000 + remap_pos++;
+    
+    if(!font->unicode2glyph) {
+       for(t=0;t<font->num_glyphs;t++) {
+           gfxglyph_t*src = &font->glyphs[t];
+           int u = font->glyphs[t].unicode;
+           if(u<=0)
+               continue;
+           if(u<32) {
+               msg("<warning> gfxfont_to_ttf: glyph %d has an invalid unicode (%d)", t, u);
+               continue;
+           } else if(ttf->unicode[u]) {
+               msg("<warning> gfxfont_to_ttf: glyph %d has a duplicate unicode (%d)", t, u);
+               continue;
+           }
+           if(u<ttf->unicode_size)
+               ttf->unicode[u] = t+offset;
        }
-       if(u>=0 && u<ttf->unicode_size)
-           ttf->unicode[u] = t+offset;
-    }
-    int u;
-    if(font->unicode2glyph) {
-       for(u=0;u<ttf->unicode_size;u++) {
+    } else {
+       int u;
+       for(u=1;u<font->max_unicode;u++) {
            int g = font->unicode2glyph[u];
-           if(invalid_unicode(u))
+           if(g>=0 && u<32) {
+               msg("<warning> gfxfont_to_ttf: Font contains an invalid unicode (%d)", u);
                continue;
+           }
            if(g>=0 && g<font->num_glyphs && !ttf->unicode[u]) {
                ttf->unicode[u] = g+offset;
            }
@@ -697,8 +742,8 @@ ttf_t* gfxfont_to_ttf(gfxfont_t*font)
     }
        
     ttf->ascent = font->ascent;
-    ttf->descent = font->descent;
-    ttf->lineGap = font->ascent - font->descent;
+    ttf->descent = -font->descent;
+    ttf->lineGap = 0;
 
     ttf->full_name = strdup(font->id);
     ttf->family_name = strdup(font->id);
@@ -713,14 +758,14 @@ ttf_t* gfxfont_to_ttf(gfxfont_t*font)
 
 void gfxfont_save(gfxfont_t*font, const char*filename)
 {
-    ttf_t*ttf = gfxfont_to_ttf(font);
+    ttf_t*ttf = gfxfont_to_ttf(font, 0);
     ttf_save(ttf, filename);
     ttf_destroy(ttf);
 }
 
 void gfxfont_save_eot(gfxfont_t*font, const char*filename)
 {
-    ttf_t*ttf = gfxfont_to_ttf(font);
+    ttf_t*ttf = gfxfont_to_ttf(font, 1);
     ttf_save_eot(ttf, filename);
     ttf_destroy(ttf);
 }