synchronized with downstream git
[swftools.git] / lib / devices / swf.c
index 48acd37..48b054a 100644 (file)
@@ -218,6 +218,10 @@ static void swf_addfont(gfxdevice_t*dev, gfxfont_t*font);
 static void swf_drawlink(gfxdevice_t*dev, gfxline_t*line, const char*action);
 static void swf_startframe(gfxdevice_t*dev, int width, int height);
 static void swf_endframe(gfxdevice_t*dev);
+static void swfoutput_namedlink(gfxdevice_t*dev, char*name, gfxline_t*points);
+static void swfoutput_linktopage(gfxdevice_t*dev, int page, gfxline_t*points);
+static void swfoutput_linktourl(gfxdevice_t*dev, const char*url, gfxline_t*points);
+
 static gfxresult_t* swf_finish(gfxdevice_t*driver);
 
 static swfoutput_internal* init_internal_struct()
@@ -802,7 +806,7 @@ static charbuffer_t*charbuffer_append(charbuffer_t*buf, SWFFONT*font, int charid
    If we set it to low, however, the char positions will be inaccurate */
 #define GLYPH_SCALE 1
 
-static void chararray_writetodev(gfxdevice_t*dev, chararray_t*array, MATRIX*matrix)
+static void chararray_writetodev(gfxdevice_t*dev, chararray_t*array, MATRIX*matrix, char invisible)
 {
     swfoutput_internal*i = (swfoutput_internal*)dev->internal;
    
@@ -832,15 +836,20 @@ static void chararray_writetodev(gfxdevice_t*dev, chararray_t*array, MATRIX*matr
        swf_SetU32(i->tag, 0);//sharpness
        swf_SetU8(i->tag, 0);//reserved
     }
-    i->tag = swf_InsertTag(i->tag,ST_PLACEOBJECT2);
-    swf_ObjectPlace(i->tag,textid,getNewDepth(dev),&i->page_matrix,NULL,NULL);
+    if(invisible && i->config_flashversion>=8) {
+       i->tag = swf_InsertTag(i->tag,ST_PLACEOBJECT3);
+       swf_ObjectPlaceBlend(i->tag,textid,getNewDepth(dev),&i->page_matrix,NULL,NULL,BLENDMODE_MULTIPLY);
+    } else {
+       i->tag = swf_InsertTag(i->tag,ST_PLACEOBJECT2);
+       swf_ObjectPlace(i->tag,textid,getNewDepth(dev),&i->page_matrix,NULL,NULL);
+    }
 }
 
-static void charbuffer_writetodevandfree(gfxdevice_t*dev, charbuffer_t*buf)
+static void charbuffer_writetodevandfree(gfxdevice_t*dev, charbuffer_t*buf, char invisible)
 {
     while(buf) {
        charbuffer_t*next = buf->next;buf->next = 0;
-       chararray_writetodev(dev, buf->array, &buf->matrix);
+       chararray_writetodev(dev, buf->array, &buf->matrix, invisible);
        chararray_destroy(buf->array);
        free(buf);
        buf = next;
@@ -852,7 +861,7 @@ static void endtext(gfxdevice_t*dev)
     swfoutput_internal*i = (swfoutput_internal*)dev->internal;
     if(!i->textmode)
         return;
-    charbuffer_writetodevandfree(dev, i->chardata);i->chardata = 0;
+    charbuffer_writetodevandfree(dev, i->chardata, 0);i->chardata = 0;
     i->textmode = 0;
 }
 
@@ -979,7 +988,7 @@ static void endpage(gfxdevice_t*dev)
     if(i->textmode)
        endtext(dev);
     if(i->topchardata) {
-       charbuffer_writetodevandfree(dev, i->topchardata);
+       charbuffer_writetodevandfree(dev, i->topchardata, 1);
        i->topchardata=0;
     }
     
@@ -1526,7 +1535,7 @@ void swfoutput_finalize(gfxdevice_t*dev)
 
     /* Add AVM2 actionscript */
     if(i->config_flashversion>=9 && 
-            (i->config_insertstoptag || i->hasbuttons)) {
+            (i->config_insertstoptag || i->hasbuttons) && !i->config_linknameurl) {
         swf_AddButtonLinks(i->swf, i->config_insertstoptag, 
                 i->config_internallinkfunction||i->config_externallinkfunction);
     }
@@ -1665,7 +1674,7 @@ static void swfoutput_setlinewidth(gfxdevice_t*dev, double _linewidth)
 }
 
 
-static void drawlink(gfxdevice_t*dev, ActionTAG*,ActionTAG*, gfxline_t*points, char mouseover, const char*url);
+static void drawlink(gfxdevice_t*dev, ActionTAG*,ActionTAG*, gfxline_t*points, char mouseover, char*type, const char*url);
 static void swfoutput_namedlink(gfxdevice_t*dev, char*name, gfxline_t*points);
 static void swfoutput_linktopage(gfxdevice_t*dev, int page, gfxline_t*points);
 static void swfoutput_linktourl(gfxdevice_t*dev, const char*url, gfxline_t*points);
@@ -1731,8 +1740,8 @@ void swfoutput_linktourl(gfxdevice_t*dev, const char*url, gfxline_t*points)
     }
     actions = action_End(actions);
    
-    drawlink(dev, actions, 0, points, 0, url);
-
+    drawlink(dev, actions, 0, points, 0, "url", url);
+    
     swf_ActionFree(actions);
 }
 void swfoutput_linktopage(gfxdevice_t*dev, int page, gfxline_t*points)
@@ -1759,7 +1768,7 @@ void swfoutput_linktopage(gfxdevice_t*dev, int page, gfxline_t*points)
     char name[80];
     sprintf(name, "page%d", page);
 
-    drawlink(dev, actions, 0, points, 0, name);
+    drawlink(dev, actions, 0, points, 0, "page", name);
     
     swf_ActionFree(actions);
 }
@@ -1779,6 +1788,7 @@ void swfoutput_namedlink(gfxdevice_t*dev, char*name, gfxline_t*points)
     if(i->textmode)
        endtext(dev);
 
+    char*type = 0;
     if(!strncmp(tmp, "call:", 5))
     {
        char*x = strchr(&tmp[5], ':');
@@ -1797,6 +1807,7 @@ void swfoutput_namedlink(gfxdevice_t*dev, char*name, gfxline_t*points)
        }
        actions2 = action_End(0);
        mouseover = 0;
+        type = "call";
     }
     else
     {
@@ -1809,9 +1820,10 @@ void swfoutput_namedlink(gfxdevice_t*dev, char*name, gfxline_t*points)
        actions2 = action_PushString(actions2, "");
        actions2 = action_SetVariable(actions2);
        actions2 = action_End(actions2);
+        type = "subtitle";
     }
 
-    drawlink(dev, actions1, actions2, points, mouseover, name);
+    drawlink(dev, actions1, actions2, points, mouseover, type, name);
 
     swf_ActionFree(actions1);
     swf_ActionFree(actions2);
@@ -1858,7 +1870,7 @@ static void drawgfxline(gfxdevice_t*dev, gfxline_t*line, int fill)
 }
 
 
-static void drawlink(gfxdevice_t*dev, ActionTAG*actions1, ActionTAG*actions2, gfxline_t*points, char mouseover, const char*url)
+static void drawlink(gfxdevice_t*dev, ActionTAG*actions1, ActionTAG*actions2, gfxline_t*points, char mouseover, char*type, const char*url)
 {
     swfoutput_internal*i = (swfoutput_internal*)dev->internal;
     RGBA rgb;
@@ -1872,6 +1884,11 @@ static void drawlink(gfxdevice_t*dev, ActionTAG*actions1, ActionTAG*actions2, gf
     int buttonid = getNewID(dev);
     gfxbbox_t bbox = gfxline_getbbox(points);
     
+    if(i->config_linknameurl) {
+        actions1 = 0;
+        actions2 = 0;
+    }
+    
     i->hasbuttons = 1;
 
     /* shape */
@@ -3055,6 +3072,10 @@ static void swf_drawchar(gfxdevice_t*dev, gfxfont_t*font, int glyph, gfxcolor_t*
            glyph, i->swffont->id, x, y, color->r, color->g, color->b, color->a);
 
     if(color->a == 0 && i->config_invisibletexttofront) {
+       if(i->config_flashversion>=8) {
+           // use "multiply" blend mode
+           color->a = color->r = color->g = color->b = 255;
+       }
        i->topchardata = charbuffer_append(i->topchardata, i->swffont, glyph, x, y, i->current_font_size, *(RGBA*)color, &i->fontmatrix);
     } else {
        i->chardata = charbuffer_append(i->chardata, i->swffont, glyph, x, y, i->current_font_size, *(RGBA*)color, &i->fontmatrix);