changed logf to msg.
[swftools.git] / pdf2swf / swfoutput.cc
index 8a129bc..172b52b 100644 (file)
    along with swftools; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
 
+#include <stdlib.h>
+#include <stdio.h>
 #include <string.h>
+#include "../config.h"
 #include <fcntl.h>
 #include <unistd.h>
+#ifdef HAVE_ASSERT_H
+#include <assert.h>
+#else
+#define assert(a)
+#endif
+#include <math.h>
 #include "swfoutput.h"
 #include "spline.h"
 extern "C" {
@@ -38,6 +47,8 @@ int storeallcharacters=0;
 int enablezlib=0;
 int insertstoptag=0;
 int flashversion=4;
+int splinemaxerror=1;
+int fontsplinemaxerror=1;
 static int flag_protected = 0;
 
 typedef unsigned char u8;
@@ -163,10 +174,10 @@ static void spline(TAG*tag,plotxy p0,plotxy p1,plotxy p2,plotxy p3,struct swfmat
 
     if(storefont) {
        /* fonts use a different approximation than shapes */
-       num = cspline_approximate(&c, q, 10.0, APPROXIMATE_RECURSIVE_BINARY);
+       num = cspline_approximate(&c, q, fontsplinemaxerror/20.0, APPROXIMATE_RECURSIVE_BINARY);
        //num = cspline_approximate(&c, q, 10.0, APPROXIMATE_INFLECTION);
     } else {
-       num = cspline_approximate(&c, q, 1.0, APPROXIMATE_RECURSIVE_BINARY);
+       num = cspline_approximate(&c, q,     splinemaxerror/20.0, APPROXIMATE_RECURSIVE_BINARY);
     }
     for(t=0;t<num;t++) {
        if(!t) 
@@ -181,8 +192,27 @@ void resetdrawer()
     swflasty = 0;
 }
 
-/* draw a T1 outline. These are generated by pdf2swf and by t1lib.
-   (representing characters) */
+static void stopFill()
+{
+    if(lastwasfill)
+    {
+     swf_ShapeSetStyle(tag,shape,linestyleid,0x8000,0);
+     fillstylechanged = 1;
+     lastwasfill = 0;
+    }
+}
+static void startFill()
+{
+    if(!lastwasfill)
+    {
+     swf_ShapeSetStyle(tag,shape,0x8000,fillstyleid,0);
+     fillstylechanged = 1;
+     lastwasfill = 1;
+    }
+}
+
+/* draw a T1 outline. These are generated by pdf2swf and by t1lib
+   (representing characters). */
 void drawpath(TAG*tag, T1_OUTLINE*outline, struct swfmatrix*m, int log)
 {
     if(tag->id != ST_DEFINEFONT &&
@@ -190,7 +220,7 @@ void drawpath(TAG*tag, T1_OUTLINE*outline, struct swfmatrix*m, int log)
         tag->id != ST_DEFINESHAPE2 &&
         tag->id != ST_DEFINESHAPE3)
     {
-        logf("<error> internal error: drawpath needs a shape tag, not %d\n",tag->id);
+        msg("<error> internal error: drawpath needs a shape tag, not %d\n",tag->id);
         exit(1);
     }
     double x=0,y=0;
@@ -251,7 +281,7 @@ void drawpath(TAG*tag, T1_OUTLINE*outline, struct swfmatrix*m, int log)
             spline(tag,p0,p1,p2,p3,m);
         } 
         else {
-         logf("<error> drawpath: unknown outline type:%d\n", outline->type);
+           msg("<error> drawpath: unknown outline type:%d\n", outline->type);
         }
         lastx=x;
         lasty=y;
@@ -272,6 +302,410 @@ void drawpath(TAG*tag, T1_OUTLINE*outline, struct swfmatrix*m, int log)
     }
 }
 
+plotxy getPivot(T1_OUTLINE*outline, int dir, double line_width, int end, int trytwo)
+{
+    T1_PATHPOINT next, next2;
+    double xv=0,yv=0, xv2=0, yv2=0;
+    plotxy p;
+    int two = 0;
+
+    if(!end) {
+       if(outline->type == T1_PATHTYPE_LINE) {
+           next = outline->dest;
+       } else {
+           next = ((T1_BEZIERSEGMENT*)outline)->B;
+           if(next.x==0 && next.y==0) {
+               next = ((T1_BEZIERSEGMENT*)outline)->C;
+           }
+           if(next.x==0 && next.y==0) {
+               next = ((T1_BEZIERSEGMENT*)outline)->dest;
+           }
+       }
+       next2 = next;
+       if(trytwo && outline->last && outline->last->type != T1_PATHTYPE_MOVE) {
+           if(outline->type == T1_PATHTYPE_LINE) {
+               next2 = outline->last->dest;
+           } else {
+               T1_PATHPOINT c = ((T1_BEZIERSEGMENT*)(outline->last))->C;
+               T1_PATHPOINT b = ((T1_BEZIERSEGMENT*)(outline->last))->B;
+               next2.x = outline->last->dest.x - c.x;
+               next2.y = outline->last->dest.y - c.y;
+               if(next2.x==0 && next2.y==0) {
+                   next2.x = outline->last->dest.x - b.x;
+                   next2.y = outline->last->dest.y - b.y;
+               }
+               if(next2.x==0 && next2.y==0) {
+                   next2.x = outline->last->dest.x;
+                   next2.y = outline->last->dest.y;
+               }
+           }
+           two = 1;
+       }
+    } else {
+       if(outline->type == T1_PATHTYPE_LINE) {
+           next = outline->dest;
+       } else {
+           T1_PATHPOINT c = ((T1_BEZIERSEGMENT*)outline)->C;
+           T1_PATHPOINT b = ((T1_BEZIERSEGMENT*)outline)->B;
+           next.x = outline->dest.x - c.x;
+           next.y = outline->dest.y - c.y;
+           if(next.x==0 && next.y==0) {
+               next.x = outline->dest.x - b.x;
+               next.y = outline->dest.y - b.y;
+           }
+           if(next.x==0 && next.y==0) {
+               next.x = outline->dest.x;
+               next.y = outline->dest.y;
+           }
+       }
+       next2 = next;
+       if(trytwo && outline->link && outline->link->type != T1_PATHTYPE_MOVE) {
+           if(outline->type == T1_PATHTYPE_LINE) {
+               next2 = outline->link->dest;
+           } else {
+               next2 = ((T1_BEZIERSEGMENT*)(outline->link))->B;
+               if(next2.x==0 && next2.y==0) {
+                   next2 = ((T1_BEZIERSEGMENT*)outline->link)->C;
+               }
+               if(next2.x==0 && next2.y==0) {
+                   next2 = ((T1_BEZIERSEGMENT*)outline->link)->dest;
+               }
+           }
+           two = 1;
+       }
+    }
+
+    if(dir) {
+       xv =  next.y/(float)0xffff;
+       yv = -next.x/(float)0xffff;
+    } else {
+       xv = -next.y/(float)0xffff;
+       yv =  next.x/(float)0xffff;
+    }
+
+    double r = (line_width/2)/sqrt(xv*xv+yv*yv);
+    xv*=r;
+    yv*=r;
+
+    if(two) {
+       if(dir) {
+           xv2 =  next2.y/(float)0xffff;
+           yv2 = -next2.x/(float)0xffff;
+       } else {
+           xv2 = -next2.y/(float)0xffff;
+           yv2 =  next2.x/(float)0xffff;
+       }
+
+       double r2 = (line_width/2)/sqrt(xv2*xv2+yv2*yv2);
+       xv2*=r2;
+       yv2*=r2;
+       xv = (xv+xv2)/2;
+       yv = (yv+yv2)/2;
+       double r3 = (line_width/2)/sqrt(xv*xv+yv*yv);
+       xv *= r3;
+       yv *= r3;
+    }
+
+    p.x = xv;
+    p.y = yv;
+    return p;
+}
+
+void drawShortPath(struct swfoutput*output, double x, double y, struct swfmatrix* m, T1_OUTLINE*outline)
+{
+    double lastx=x, lasty=y;
+    while (outline && outline->type != T1_PATHTYPE_MOVE)
+    {
+        x += (outline->dest.x/(float)0xffff);
+        y += (outline->dest.y/(float)0xffff);
+
+        if(outline->type == T1_PATHTYPE_LINE)
+        {
+            plotxy p0, p1;
+            p0.x=lastx;
+           p0.y=lasty;
+            p1.x= x; 
+           p1.y= y;
+            line(tag, p0, p1, m);
+        }
+        else if(outline->type == T1_PATHTYPE_BEZIER)
+        {
+            plotxy p0,p1,p2,p3;
+            T1_BEZIERSEGMENT*o2 = (T1_BEZIERSEGMENT*)outline;
+            p3.x=lastx;
+           p3.y=lasty;
+            p1.x=o2->C.x/(float)0xffff+lastx;
+            p1.y=o2->C.y/(float)0xffff+lasty;
+            p2.x=o2->B.x/(float)0xffff+lastx;
+            p2.y=o2->B.y/(float)0xffff+lasty;
+            p0.x=x; 
+           p0.y=y;
+            spline(tag,p0,p1,p2,p3,m);
+        } 
+        lastx=x;
+        lasty=y;
+        outline = outline->link;
+    }
+}
+
+void drawShortPathWithEnds(struct swfoutput*output, double x, double y, struct swfmatrix* m, T1_OUTLINE*outline, int num, int line_cap, int line_join, double line_width)
+{
+    plotxy d,d2;
+    int back = 0;
+
+    if(line_cap == LINE_CAP_BUTT || line_cap == LINE_CAP_SQUARE) {
+       endshape();
+       startshape(output);
+       T1_OUTLINE *last, *tmp=outline;
+       plotxy s,e,p0,p1,p2,p3,m0,m1,m2,m3;
+       double x2 = x;
+       double y2 = y;
+       double lx=x,ly=y;
+       double ee = 1.0;
+       int nr;
+       while(tmp && tmp->type != T1_PATHTYPE_MOVE) {
+           last = tmp;
+           lx += (tmp->dest.x/(float)0xffff);
+           ly += (tmp->dest.y/(float)0xffff);
+           tmp = tmp->link;
+       }
+       s = getPivot(outline, 0, line_width, 0, 0);
+       e = getPivot(last, 0, line_width, 1, 0);
+
+       if(line_cap == LINE_CAP_BUTT) {
+           /* make the clipping rectangle slighly bigger
+              than the line ending, so that it get's clipped
+              propertly */
+           //ee = 1.01;
+           ee=1.0;
+       }
+
+       p0.x = x2 + s.x*ee; 
+       p0.y = y2 + s.y*ee;
+       p1.x = x2 - s.x*ee; 
+       p1.y = y2 - s.y*ee;
+       p2.x = x2 - s.y - s.x*ee; 
+       p2.y = y2 + s.x - s.y*ee;
+       p3.x = x2 - s.y + s.x*ee; 
+       p3.y = y2 + s.x + s.y*ee;
+       m0.x = lx + e.x*ee; 
+       m0.y = ly + e.y*ee;
+       m1.x = lx - e.x*ee; 
+       m1.y = ly - e.y*ee;
+       m2.x = lx + e.y - e.x*ee; 
+       m2.y = ly - e.x - e.y*ee;
+       m3.x = lx + e.y + e.x*ee; 
+       m3.y = ly - e.x + e.y*ee;
+
+       for(nr=0;nr<2;nr++) {
+           int dir=0;
+           struct plotxy q0,q1,q2,q3,q4,q5;
+           startFill();
+           if(line_cap == LINE_CAP_BUTT) {
+               if(dir) {
+                   q0.x = 0; q0.y = 0;
+                   q1.x = sizex; q1.y = 0;
+                   q2.x = sizex; q2.y = sizey;
+                   q3.x = 0; q3.y = sizey;
+               } else {
+                   q0.x = sizex; q0.y = sizey;
+                   q1.x = 0; q1.y = sizey;
+                   q2.x = 0; q2.y = 0;
+                   q3.x = sizex; q3.y = 0;
+               }
+               q4.x = p0.x; 
+               q4.y = p0.y;
+               moveto(tag, q0);
+               lineto(tag, q1);
+               lineto(tag, q2);
+               lineto(tag, q3);
+               lineto(tag, q0);
+
+               transform(&q4,m);
+               lineto(tag, q4);
+           }
+
+           line(tag, p0, p1, m);
+           line(tag, p1, p2, m);
+           line(tag, p2, p3, m);
+           line(tag, p3, p0, m);
+
+           if(line_cap == LINE_CAP_BUTT) {
+               lineto(tag, q0);
+               swf_ShapeSetEnd(tag);
+               tag = swf_InsertTag(tag, ST_PLACEOBJECT2);
+               swf_ObjectPlaceClip(tag,shapeid,depth,NULL,NULL,NULL,depth+2-nr);
+               depth++;
+               shapeid = -1;
+               startshape(output);
+           }
+           p0 = m0;
+           p1 = m1;
+           p2 = m2;
+           p3 = m3;
+       }
+
+       stopFill();
+    }
+
+    drawShortPath(output,x,y,m,outline);
+
+    if(line_cap == LINE_CAP_BUTT) {
+       endshape();
+       startshape(output);
+    }
+}
+
+void drawT1toRect(struct swfoutput*output, double x, double y, struct swfmatrix* m, T1_OUTLINE*outline, int num, int line_cap, int line_join, double line_width)
+{
+    plotxy d1,d2,p1,p2,p3,p4;
+
+    d1.x = (outline->dest.x/(float)0xffff);
+    d1.y = (outline->dest.y/(float)0xffff);
+    d2 = getPivot(outline, 0, line_width, 0, 0);
+
+    assert(line_cap != LINE_CAP_ROUND);
+    if(line_cap == LINE_CAP_SQUARE) {
+       x -= +d2.y;
+       y -= -d2.x;
+       d1.x += +2*d2.y;
+       d1.y += -2*d2.x;
+    }
+
+    p1.x = x + d2.x;
+    p1.y = y + d2.y;
+    p2.x = x + d2.x + d1.x;
+    p2.y = y + d2.y + d1.y;
+    p3.x = x - d2.x + d1.x;
+    p3.y = y - d2.y + d1.y;
+    p4.x = x - d2.x;
+    p4.y = y - d2.y;
+
+    line(tag, p1,p2, m);
+    line(tag, p2,p3, m);
+    line(tag, p3,p4, m);
+    line(tag, p4,p1, m);
+}
+
+void drawShortPathWithStraightEnds(struct swfoutput*output, double x, double y, struct swfmatrix* m, T1_OUTLINE*outline, int num, int line_cap, int line_join, double line_width)
+{
+    T1_OUTLINE*tmp=outline;
+    double xx=x,yy=y;
+    int stop=0;
+    assert(shapeid>=0);
+
+    startFill();
+    drawT1toRect(output, x, y, m,outline, num, line_cap, line_join, line_width);
+
+    while(tmp->link && tmp->link->type!=T1_PATHTYPE_MOVE) {
+        xx += (tmp->dest.x/(float)0xffff);
+        yy += (tmp->dest.y/(float)0xffff);
+       tmp = tmp->link;
+    }
+    
+    assert(tmp->type == T1_PATHTYPE_LINE);
+    assert(outline->type == T1_PATHTYPE_LINE);
+    
+    if(tmp!=outline) {
+   
+       if(outline->link == tmp) {
+           /* the two straight line segments (which are everything we
+              need to draw) are very likely to overlap. To avoid that
+              they cancel each other out at the end points, start a new
+              shape for the second one */
+           endshape();startshape(output);
+           startFill();
+       }
+
+       drawT1toRect(output, xx, yy, m, tmp, num, line_cap, line_join, line_width);
+
+       if(outline->link != tmp)
+       {
+           stopFill();stop=1;
+           int save= tmp->type;
+           tmp->type = T1_PATHTYPE_MOVE;
+           x += (outline->dest.x/(float)0xffff);
+           y += (outline->dest.y/(float)0xffff);
+           outline = outline->link;
+           drawShortPath(output, x, y, m, outline);
+           tmp->type = save;
+       }
+    }
+    if(!stop)
+       stopFill();
+}
+
+static int t1len(T1_OUTLINE*line)
+{
+    int num=0;
+    while(line && line->type != T1_PATHTYPE_MOVE) {
+       num++;
+       line = line->link;
+    }
+    return num;
+}
+
+static float t1linelen(T1_OUTLINE*line)
+{
+    float x,y;
+    x = (line->dest.x/(float)0xffff);
+    y = (line->dest.y/(float)0xffff);
+    return sqrt(x*x+y*y);
+}
+
+void drawpath2poly(struct swfoutput *output, T1_OUTLINE*outline, struct swfmatrix*m, int log, int line_join, int line_cap, double line_width, double miter_limit)
+{
+    if(tag->id != ST_DEFINEFONT &&
+        tag->id != ST_DEFINESHAPE &&
+        tag->id != ST_DEFINESHAPE2 &&
+        tag->id != ST_DEFINESHAPE3) {
+        msg("<error> internal error: drawpath needs a shape tag, not %d\n",tag->id);
+        exit(1);
+    }
+    assert(shapeid>=0);
+    double x=0,y=0;
+    double lastx=0,lasty=0;
+    int valid = 0;
+    int lastwasline = 0;
+    T1_OUTLINE*tmp = outline, *last = 0;
+    tmp->last = 0;
+
+    while(1) {
+       if(tmp) {
+           x += (tmp->dest.x/(float)0xffff);
+           y += (tmp->dest.y/(float)0xffff);
+       }
+        if(!tmp || tmp->type == T1_PATHTYPE_MOVE) {
+           if(valid && last) {
+               if(last->type == T1_PATHTYPE_LINE && t1linelen(last)>line_width*2 &&
+                  lastwasline && line_cap != LINE_CAP_ROUND)
+                   drawShortPathWithStraightEnds(output, lastx, lasty, m, last, valid, line_cap, line_join, line_width);
+               else
+                   drawShortPathWithEnds(output, lastx, lasty, m, last, valid, line_cap, line_join, line_width);
+           }
+           if(!tmp)
+               break;
+           valid = 0;
+           last = 0;
+           lastx = x;
+           lasty = y;
+       } else {
+           if(!last)
+               last = tmp;
+           valid++;
+       }
+
+       if(tmp && tmp->type == T1_PATHTYPE_LINE && t1linelen(tmp)>line_width*2)
+           lastwasline = 1;
+       else
+           lastwasline = 0;
+
+       if(tmp->link)
+           tmp->link->last = tmp; // make sure list is properly linked in both directions
+       tmp = tmp->link;
+    }
+}
+
 static inline int colorcompare(RGBA*a,RGBA*b)
 {
 
@@ -317,11 +751,11 @@ static void putcharacters(TAG*tag)
 
     if(tag->id != ST_DEFINETEXT &&
         tag->id != ST_DEFINETEXT2) {
-        logf("<error> internal error: putcharacters needs an text tag, not %d\n",tag->id);
+        msg("<error> internal error: putcharacters needs an text tag, not %d\n",tag->id);
         exit(1);
     }
     if(!chardatapos) {
-        logf("<warning> putcharacters called with zero characters");
+        msg("<warning> putcharacters called with zero characters");
     }
 
     for(pass = 0; pass < 2; pass++)
@@ -470,7 +904,7 @@ static void drawchar(struct swfoutput*obj, SWFFont*font, char*character, int cha
         char* charname = character;
 
         if(!outline) {
-         logf("<warning> Didn't find %s in current charset (%s)", 
+         msg("<warning> Didn't find %s in current charset (%s)", 
                  FIXNULL(character),FIXNULL(font->getName()));
          return;
         }
@@ -486,11 +920,7 @@ static void drawchar(struct swfoutput*obj, SWFFont*font, char*character, int cha
         if(shapeid<0)
             startshape(obj);
 
-        if(!lastwasfill) {
-         swf_ShapeSetStyle(tag,shape,0x8000,fillstyleid,0);
-        fillstylechanged = 1;
-       }
-        lastwasfill = 1;
+       startFill();
 
         int lf = fill;
         fill = 1;
@@ -516,22 +946,27 @@ void swfoutput_drawpath(swfoutput*output, T1_OUTLINE*outline,
     if(shapeid<0)
         startshape(output);
 
-    if(lastwasfill && !fill)
-    {
-     swf_ShapeSetStyle(tag,shape,linestyleid,0x8000,0);
-     fillstylechanged = 1;
-     lastwasfill = 0;
-    }
-    if(!lastwasfill && fill)
-    {
-     swf_ShapeSetStyle(tag,shape,0x8000,fillstyleid,0);
-     fillstylechanged = 1;
-     lastwasfill = 1;
-    }
+    if(!fill)
+       stopFill();
+    else
+       startFill();
 
     drawpath(tag, outline,m, 0); 
 }
 
+void swfoutput_drawpath2poly(struct swfoutput*output, T1_OUTLINE*outline, struct swfmatrix*m, int line_join, int line_cap, double line_width, double miter_limit)
+{
+    if(textid>=0)
+        endtext();
+    if(shapeid>=0)
+       endshape();
+    assert(shapeid<0);
+    startshape(output);
+    stopFill();
+
+    drawpath2poly(output, outline, m, 0, line_join, line_cap, line_width, miter_limit); 
+}
+
 /* SWFFont: copy all t1 font outlines to a local 
    array. */
 SWFFont::SWFFont(char*name, int id, char*filename)
@@ -554,7 +989,7 @@ SWFFont::SWFFont(char*name, int id, char*filename)
 
     if(!charnum) 
         return;
-    logf("<verbose> Font %s(%d): Storing %d outlines.\n", FIXNULL(name), id, charnum);
+    msg("<verbose> Font %s(%d): Storing %d outlines.\n", FIXNULL(name), id, charnum);
 
     this->standardtablesize = 256;
     if(this->charnum < this->standardtablesize)
@@ -640,7 +1075,7 @@ SWFFont::~SWFFont()
 
     if(usednum && !drawonlyshapes)
     {
-        logf("<verbose> Font %s has %d used characters",FIXNULL(fontid), usednum);
+        msg("<verbose> Font %s has %d used characters",FIXNULL(fontid), usednum);
         TAG*ftag = swf_InsertTag(swf.firstTag,ST_DEFINEFONT);
         swf_SetU16(ftag, this->swfid);
         int initpos = swf_GetTagLen(ftag);
@@ -736,7 +1171,7 @@ T1_OUTLINE*SWFFont::getOutline(char*name, int charnr)
        return getOutline(this->standardtable[charnr], -1);
     }
 
-    logf("<warning> Didn't find character '%s' in font '%s'", FIXNULL(name), this->name);
+    msg("<warning> Didn't find character '%s' in font '%s'", FIXNULL(name), this->name);
     return 0;
 }
 
@@ -774,7 +1209,7 @@ int SWFFont::getSWFCharID(char*name, int charnr)
     if(this->standardtable && charnr>=0 && charnr < this->standardtablesize) {
        return getSWFCharID(this->standardtable[charnr], -1);
     }
-    logf("<warning> Didn't find character '%s' in font '%s'", FIXNULL(name), this->name);
+    msg("<warning> Didn't find character '%s' in font '%s'", FIXNULL(name), this->name);
     return 0;
 }
 
@@ -821,7 +1256,7 @@ void swfoutput_setfont(struct swfoutput*obj, char*fontid, int t1id, char*filenam
     }
 
     if(t1id<0) {
-        logf("<error> internal error: t1id:%d, fontid:%s\n", t1id,FIXNULL(fontid));
+        msg("<error> internal error: t1id:%d, fontid:%s\n", t1id,FIXNULL(fontid));
     }
     
     SWFFont*font = new SWFFont(fontid, t1id, filename);
@@ -889,7 +1324,7 @@ void swfoutput_init(struct swfoutput* obj, char*_filename, int _sizex, int _size
   sizex = _sizex;
   sizey = _sizey;
 
-  logf("<verbose> initializing swf output for size %d*%d\n", sizex,sizey);
+  msg("<verbose> initializing swf output for size %d*%d\n", sizex,sizey);
 
   obj->font = 0;
   
@@ -1057,7 +1492,7 @@ void swfoutput_destroy(struct swfoutput* obj)
      fi = 1; // stdout
     
     if(fi<=0) {
-     logf("<fatal> Could not create \"%s\". ", FIXNULL(filename));
+     msg("<fatal> Could not create \"%s\". ", FIXNULL(filename));
      exit(1);
     }
  
@@ -1065,15 +1500,15 @@ void swfoutput_destroy(struct swfoutput* obj)
 
     if(enablezlib) {
       if FAILED(swf_WriteSWC(fi,&swf)) 
-       logf("<error> WriteSWC() failed.\n");
+       msg("<error> WriteSWC() failed.\n");
     } else {
       if FAILED(swf_WriteSWF(fi,&swf)) 
-       logf("<error> WriteSWF() failed.\n");
+       msg("<error> WriteSWF() failed.\n");
     }
 
     if(filename)
      close(fi);
-    logf("<notice> SWF written\n");
+    msg("<notice> SWF written\n");
 }
 
 void swfoutput_setdrawmode(swfoutput* obj, int mode)
@@ -1141,7 +1576,7 @@ void swfoutput_startclip(swfoutput*obj, T1_OUTLINE*outline, struct swfmatrix*m)
 
     if(clippos >= 127)
     {
-        logf("<warning> Too many clip levels.");
+        msg("<warning> Too many clip levels.");
         clippos --;
     } 
     
@@ -1168,7 +1603,7 @@ void swfoutput_endclip(swfoutput*obj)
      endshape();
 
     if(!clippos) {
-        logf("<error> Invalid end of clipping region");
+        msg("<error> Invalid end of clipping region");
         return;
     }
     clippos--;