reworked font backend
[swftools.git] / lib / pdf / InfoOutputDev.cc
index 13733cb..ec54572 100644 (file)
@@ -1,5 +1,6 @@
 #include "SplashTypes.h"
 #include "SplashOutputDev.h"
+#include "SplashPath.h"
 #include "InfoOutputDev.h"
 #include "GfxState.h"
 #include "../log.h"
@@ -10,18 +11,49 @@ InfoOutputDev::InfoOutputDev(XRef*xref)
     num_links = 0;
     num_images = 0;
     num_fonts = 0;
-    id2font = new GHash();
+    id2font = new GHash(1);
     SplashColor white = {255,255,255};
-    //splash = new SplashOutputDev(splashModeRGB8,320,0,white,0,0);
-    //splash->startDoc(xref);
+    splash = new SplashOutputDev(splashModeRGB8,320,0,white,0,0);
+    splash->startDoc(xref);
 }
 InfoOutputDev::~InfoOutputDev() 
 {
+    GHashIter*i;
+    id2font->startIter(&i);
+    GString*key;
+    FontInfo*fontinfo;
+    while(id2font->getNext(&i, &key, (void**)&fontinfo)) {
+       delete fontinfo;
+    }
+    id2font->killIter(&i);
+
     delete id2font;
+    delete splash;
+}
+FontInfo::FontInfo()
+{
+    this->charid2glyph = 0;
+}
+FontInfo::~FontInfo()
+{
+    this->font = 0;
+    if(this->charid2glyph) {
+       free(this->charid2glyph);
+       this->charid2glyph = 0;
+    }
+    int t;
+    for(t=0;t<num_glyphs;t++) {
+       if(glyphs[t]) {
+           delete glyphs[t]->path;glyphs[t]->path = 0;
+           delete glyphs[t];
+           glyphs[t]=0;
+       }
+    }
 }
 GBool InfoOutputDev::upsideDown() {return gTrue;}
 GBool InfoOutputDev::useDrawChar() {return gTrue;}
 GBool InfoOutputDev::interpretType3Chars() {return gTrue;}
+GBool InfoOutputDev::useTilingPatternFill() {return gTrue;}
 void InfoOutputDev::startPage(int pageNum, GfxState *state, double crop_x1, double crop_y1, double crop_x2, double crop_y2)
 {
     double x1,y1,x2,y2;
@@ -49,7 +81,7 @@ double InfoOutputDev::getMaximumFontSize(char*id)
     return info->max_size;
 }
 
-static char*getFontID(GfxFont*font)
+char*getFontID(GfxFont*font)
 {
     Ref*ref = font->getID();
     GString*gstr = font->getName();
@@ -68,24 +100,46 @@ void InfoOutputDev::updateFont(GfxState *state)
     GfxFont*font = state->getFont();
     if(!font)
        return;
+    if(font->getType() == fontType3) {
+       return;
+    }
     char*id = getFontID(font);
-    
+
     FontInfo*info = (FontInfo*)id2font->lookup(id);
-    if(!info) {
-      GString* idStr = new GString(id);
-      info = new FontInfo;
-      info->font = font;
-      info->max_size = 0;
-      id2font->add(idStr, (void*)info);
-      free(id);
-      num_fonts++;
+    if(info) {
+       /* font already known */
+       free(id);
+       currentfont = info;
+       return;
     }
-    currentfont = info;
 
-    //splash->doUpdateFont(state);
-    //SplashFont* splash_font = splash->getCurrentFont();
+    info = new FontInfo;
+    info->font = font;
+    info->max_size = 0;
+
+    state->setCTM(1.0,0,0,1.0,0,0);
+    splash->updateCTM(state, 0,0,0,0,0,0);
+    state->setTextMat(1.0,0,0,-1.0,0,0);
+    state->setFont(font, 1024.0);
+    splash->doUpdateFont(state);
+    info->splash_font = splash->getCurrentFont();
+    info->num_glyphs = 0;
+    info->glyphs = 0;
 
-    //printf("%s: %d chars\n", id, splash_font->getNumChars());
+    if(!info->splash_font) {
+       delete info;
+       return;
+    }
+    GString* idStr = new GString(id);
+    id2font->add(idStr, (void*)info);
+    num_fonts++;
+    currentfont = info;
+    free(id);
+}
+FontInfo* InfoOutputDev::getFont(char*id)
+{
+    return (FontInfo*)id2font->lookup(id);
 }
 
 void InfoOutputDev::drawChar(GfxState *state, double x, double y,
@@ -93,9 +147,6 @@ void InfoOutputDev::drawChar(GfxState *state, double x, double y,
                      double originX, double originY,
                      CharCode code, int nBytes, Unicode *u, int uLen)
 {
-    int render = state->getRender();
-    if (render == 3)
-       return;
     double m11,m21,m12,m22;
     state->getFontTransMat(&m11, &m12, &m21, &m22);
     m11 *= state->getHorizScaling();
@@ -106,6 +157,21 @@ void InfoOutputDev::drawChar(GfxState *state, double x, double y,
     if(currentfont && currentfont->max_size < len) {
        currentfont->max_size = len;
     }
+    if(code >= currentfont->num_glyphs) {
+       currentfont->glyphs = (GlyphInfo**)realloc(currentfont->glyphs, sizeof(GlyphInfo*)*(code+1));
+       memset(&currentfont->glyphs[currentfont->num_glyphs], 0, sizeof(SplashPath*)*((code+1)-currentfont->num_glyphs));
+       currentfont->num_glyphs = code+1;
+    }
+    GlyphInfo*g = currentfont->glyphs[code];
+    if(!g) {
+       g = currentfont->glyphs[code] = new GlyphInfo();
+       g->path = currentfont->splash_font->getGlyphPath(code);
+       g->unicode = 0;
+    }
+    if(uLen && (u[0]>=32 && u[0]<g->unicode || !g->unicode)) {
+       g->unicode = u[0];
+    }
+
 }
 void InfoOutputDev::drawImageMask(GfxState *state, Object *ref, Stream *str,
                           int width, int height, GBool invert,