added type3 char handling
[swftools.git] / lib / pdf / InfoOutputDev.cc
index ec54572..1d22a8b 100644 (file)
@@ -30,9 +30,20 @@ InfoOutputDev::~InfoOutputDev()
     delete id2font;
     delete splash;
 }
+void FontInfo::grow(int size)
+{
+    if(size >= this->num_glyphs) {
+       this->glyphs = (GlyphInfo**)realloc(this->glyphs, sizeof(GlyphInfo*)*(size));
+       memset(&this->glyphs[this->num_glyphs], 0, sizeof(SplashPath*)*((size)-this->num_glyphs));
+       this->num_glyphs = size;
+    }
+}
 FontInfo::FontInfo()
 {
     this->charid2glyph = 0;
+    this->seen = 0;
+    this->num_glyphs = 0;
+    this->glyphs = 0;
 }
 FontInfo::~FontInfo()
 {
@@ -54,6 +65,7 @@ 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;
@@ -88,7 +100,11 @@ char*getFontID(GfxFont*font)
     char* fname = gstr==0?0:gstr->getCString();
     char buf[128];
     if(fname==0) {
-       sprintf(buf, "font-%d-%d", ref->num, ref->gen);
+       if(font->getType() == fontType3) {
+           sprintf(buf, "t3font-%d-%d", ref->num, ref->gen);
+       } else {
+           sprintf(buf, "font-%d-%d", ref->num, ref->gen);
+       }
     } else {
        sprintf(buf, "%s-%d-%d", fname, ref->num, ref->gen);
     }
@@ -123,8 +139,6 @@ void InfoOutputDev::updateFont(GfxState *state)
     state->setFont(font, 1024.0);
     splash->doUpdateFont(state);
     info->splash_font = splash->getCurrentFont();
-    info->num_glyphs = 0;
-    info->glyphs = 0;
 
     if(!info->splash_font) {
        delete info;
@@ -157,11 +171,7 @@ 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;
-    }
+    currentfont->grow(code+1);
     GlyphInfo*g = currentfont->glyphs[code];
     if(!g) {
        g = currentfont->glyphs[code] = new GlyphInfo();
@@ -173,6 +183,71 @@ void InfoOutputDev::drawChar(GfxState *state, double x, double y,
     }
 
 }
+
+GBool InfoOutputDev::beginType3Char(GfxState *state, double x, double y, double dx, double dy, CharCode code, Unicode *u, int uLen)
+{
+    GfxFont*font = state->getFont();
+    if(!font)
+       return gTrue;
+    if(font->getType() != fontType3)
+       return gTrue;
+
+    char*id = getFontID(font);
+    currentfont = (FontInfo*)id2font->lookup(id);
+    if(!currentfont) {
+       currentfont = new FontInfo;
+       currentfont->font = font;
+       GString* idStr = new GString(id);
+       id2font->add(idStr, (void*)currentfont);
+       num_fonts++;
+    }
+    currentfont = currentfont;
+    free(id);
+
+    currentfont->grow(code+1);
+    if(!currentfont->glyphs[code]) {
+       currentglyph = currentfont->glyphs[code] = new GlyphInfo();
+       currentglyph->unicode = uLen?u[0]:0;
+       currentglyph->path = new SplashPath();
+       currentglyph->x1=0;
+       currentglyph->y1=0;
+       currentglyph->x2=dx;
+       currentglyph->y2=-dy;
+       return gFalse;
+    } else {
+       return gTrue;
+    }
+}
+
+void InfoOutputDev::type3D0(GfxState *state, double wx, double wy)
+{
+    currentglyph->x1=0;
+    currentglyph->y1=0;
+    currentglyph->x2=wx;
+    currentglyph->y2=-wy;
+}
+
+void InfoOutputDev::type3D1(GfxState *state, double wx, double wy, double llx, double lly, double urx, double ury)
+{
+    currentglyph->x1=llx;
+    currentglyph->y1=-lly;
+    currentglyph->x2=urx;
+    currentglyph->y2=-ury;
+}
+
+void InfoOutputDev::endType3Char(GfxState *state)
+{
+    double x1 = currentglyph->x1;
+    double y1 = currentglyph->y1;
+    double x2 = currentglyph->x2;
+    double y2 = currentglyph->y2;
+    currentglyph->path->moveTo(x1,y1);
+    currentglyph->path->lineTo(x2,y1);
+    currentglyph->path->lineTo(x2,y2);
+    currentglyph->path->lineTo(x1,y2);
+    currentglyph->path->close();
+}
+
 void InfoOutputDev::drawImageMask(GfxState *state, Object *ref, Stream *str,
                           int width, int height, GBool invert,
                           GBool inlineImg)