fixed space handling in drawChar()
[swftools.git] / pdf2swf / SWFOutputDev.cc
index 4468997..a949fe0 100644 (file)
@@ -163,7 +163,7 @@ public:
   virtual void startPage(int pageNum, GfxState *state, double x1, double y1, double x2, double y2) ;
 
   void endframe();
-  void* getSWF();
+  void* get(char*name);
 
   //----- get info about output device
 
@@ -304,6 +304,51 @@ public:
   friend void swf_output_preparepage(swf_output_t*swf, int pdfpage, int outputpage);
 };
 
+typedef struct _drawnchar
+{
+    gfxcoord_t x,y;
+    int charid;
+    gfxcolor_t color;
+} drawnchar_t;
+
+class CharBuffer
+{
+    drawnchar_t * chars;
+    int buf_size;
+    int num_chars;
+
+public:
+
+    CharBuffer()
+    {
+       buf_size = 32;
+       chars = (drawnchar_t*)malloc(sizeof(drawnchar_t)*buf_size);
+       memset(chars, 0, sizeof(drawnchar_t)*buf_size);
+       num_chars = 0;
+    }
+    ~CharBuffer()
+    {
+       free(chars);chars = 0;
+    }
+
+    void grow(int size)
+    {
+       if(size>=buf_size) {
+           buf_size += 32;
+           chars = (drawnchar_t*)realloc(chars, sizeof(drawnchar_t)*buf_size);
+       }
+    }
+
+    void addChar(int charid, gfxcoord_t x, gfxcoord_t y, gfxcolor_t color)
+    {
+       grow(num_chars);
+       chars[num_chars].x = x;
+       chars[num_chars].y = y;
+       chars[num_chars].color = color;
+       chars[num_chars].charid = charid;
+    }
+};
+
 static char*getFontID(GfxFont*font);
 
 struct FontInfo
@@ -975,10 +1020,10 @@ int SWFOutputDev::save(char*filename)
     finish();
     return result->save(result, filename);
 }
-void* SWFOutputDev::getSWF()
+void* SWFOutputDev::get(char*name)
 {
     finish();
-    return result->get(result, "swf");
+    return result->get(result, name);
 }
 
 SWFOutputDev::~SWFOutputDev() 
@@ -1135,8 +1180,10 @@ void SWFOutputDev::drawChar(GfxState *state, double x, double y,
 {
     int render = state->getRender();
     // check for invisible text -- this is used by Acrobat Capture
-    if (render == 3)
+    if (render == 3) {
+       msg("<debug> Ignoring invisible text: char %d at %f,%f", c, x, y);
        return;
+    }
 
     if(states[statepos].textRender != render)
        msg("<error> Internal error: drawChar.render!=beginString.render");
@@ -1180,8 +1227,9 @@ void SWFOutputDev::drawChar(GfxState *state, double x, double y,
        Gfx8BitFont*font8;
        font8 = (Gfx8BitFont*)font;
        char**enc=font8->getEncoding();
-       if(enc && enc[c])
+       if(enc && enc[c] && strcasecmp(enc[c], "space")) {
           name = enc[c];
+       }
     }
     if (CIDToGIDMap) {
        msg("<debug> drawChar(%f, %f, c='%c' (%d), GID=%d, u=%d <%d>) CID=%d name=\"%s\" render=%d\n", x, y, (c&127)>=32?c:'?', c, CIDToGIDMap[c], u, uLen, font->isCIDFont(), FIXNULL(name), render);
@@ -1190,8 +1238,26 @@ void SWFOutputDev::drawChar(GfxState *state, double x, double y,
        msg("<debug> drawChar(%f,%f,c='%c' (%d), u=%d <%d>) CID=%d name=\"%s\" render=%d\n",x,y,(c&127)>=32?c:'?',c,u, uLen, font->isCIDFont(), FIXNULL(name), render);
     }
 
-    int charid = getGfxCharID(current_gfxfont, c, name, u);
-    if(charid<0) {
+    int charid = -1;
+   
+    if(uLen<=1) {
+       charid = getGfxCharID(current_gfxfont, c, name, u);
+    } else {
+       charid = getGfxCharID(current_gfxfont, c, 0, -1);
+       if(charid < 0) {
+           /* multiple unicodes- should usually map to a ligature.
+              if the ligature doesn't exist, we need to draw
+              the characters one-by-one. */
+           int t;
+           msg("<warning> ligature %d missing in font %s\n", c, current_font_id);
+           for(t=0;t<uLen;t++) {
+               drawChar(state, x, y, dx, dy, originX, originY, c, _u+t, 1);
+           }
+           return;
+       }
+    }
+
+    if(charid<0 && name) {
        if(strcasecmp(name, "space")) {
            msg("<warning> Didn't find character '%s' (c=%d,u=%d) in current charset (%s, %d characters)", 
                    FIXNULL(name),c, u, FIXNULL((char*)current_font_id), current_gfxfont->num_glyphs);
@@ -2792,10 +2858,10 @@ int swf_output_save(swf_output_t*swf, char*filename)
     return ret;
 }
 
-void* swf_output_get(swf_output_t*swf)
+void* swf_output_get(swf_output_t*swf,char*name)
 {
     swf_output_internal_t*i= (swf_output_internal_t*)swf->internal;
-    void* ret = i->outputDev->getSWF();
+    void* ret = i->outputDev->get(name);
     return ret;
 }