bugfix in spline conversion
[swftools.git] / lib / devices / opengl.c
index 2a57216..a9459a1 100644 (file)
@@ -15,7 +15,6 @@
 
 typedef struct _fontlist {
     gfxfont_t*font;
-    char*id;
     struct _fontlist*next;
 } fontlist_t;
 
@@ -30,8 +29,7 @@ typedef struct _internal {
     GLUtesselator *tesselator_tex;
 } internal_t;
 
-int verbose = 1;
-
+static int verbose = 1;
 static void dbg(char*format, ...)
 {
     char buf[1024];
@@ -77,6 +75,15 @@ void CALLBACK vertexCallback(GLvoid *vertex)
    double*xyz = (GLdouble*)vertex;
    glVertex3d(xyz[0],xyz[1],xyz[2]);
 }
+void CALLBACK combineCallback(GLdouble coords[3], GLdouble *data[4], GLfloat w[4], GLdouble **out)
+{
+   GLdouble *vertex;
+   vertex = (GLdouble *) malloc(6 * sizeof(GLdouble));
+   vertex[0] = coords[0];
+   vertex[1] = coords[1];
+   vertex[2] = coords[2];
+   *out = vertex;
+}
 void CALLBACK vertexCallbackTex(GLvoid *vertex)
 {
    double*v = (GLdouble*)vertex;
@@ -123,6 +130,7 @@ void opengl_endclip(struct _gfxdevice*dev)
 
 void opengl_stroke(struct _gfxdevice*dev, gfxline_t*line, gfxcoord_t width, gfxcolor_t*color, gfx_capType cap_style, gfx_joinType joint_style, gfxcoord_t miterLimit)
 {
+    dbg("stroke");
     internal_t*i = (internal_t*)dev->internal;
     char running = 0;
     gfxline_t*l=0;
@@ -154,10 +162,12 @@ void opengl_stroke(struct _gfxdevice*dev, gfxline_t*line, gfxcoord_t width, gfxc
 
 void opengl_fill(struct _gfxdevice*dev, gfxline_t*line, gfxcolor_t*color)
 {
+    dbg("fill");
     internal_t*i = (internal_t*)dev->internal;
     char running = 0;
     int len = 0;
     double*xyz=0;
+    double lastx=0,lasty=0;
     gfxline_t*l=0;
     dbg("fill");
     glColor4f(color->r/255.0, color->g/255.0, color->b/255.0, color->a/255.0);
@@ -166,9 +176,18 @@ void opengl_fill(struct _gfxdevice*dev, gfxline_t*line, gfxcolor_t*color)
     l = line;
     len = 0;
     while(l) {
-       len++;
+       if(l->type == gfx_splineTo) {
+            double c = sqrt(abs(l->x-2*l->sx+lastx) + abs(l->y-2*l->sy+lasty))/2;
+           int steps = (int)c;
+           if(steps<1) steps = 1;
+           len += steps;
+       } else {
+           len++;
+       }
        l = l->next;
     }
+    //printf("full len:%d\n", len);
+    double z = (i->currentz*ZSTEP);
     xyz = malloc(sizeof(double)*3*len);
     l = line;
     len = 0;
@@ -184,11 +203,33 @@ void opengl_fill(struct _gfxdevice*dev, gfxline_t*line, gfxcolor_t*color)
            gluTessBeginContour(i->tesselator);
        }
 
-       xyz[len*3+0] = l->x;
-       xyz[len*3+1] = l->y;
-       xyz[len*3+2] = (i->currentz*ZSTEP);
-       gluTessVertex(i->tesselator, &xyz[len*3], &xyz[len*3]);
-       len++;
+       if(l->type == gfx_splineTo) {
+           int j;
+            double c = sqrt(abs(l->x-2*l->sx+lastx) + abs(l->y-2*l->sy+lasty))/2;
+           int steps = (int)c;
+           if(steps<1) steps = 1;
+           //printf("c=%f d1=%f (%f/%f) d2=%f (%f/%f)\n", c,d1,l->x-l->sx,l->y-l->sy,d2,lastx-l->sx,lasty-l->sy);
+           //printf("%f %f %f\n", lastx, l->sx, l->x);
+           //printf("%f %f %f\n", lasty, l->sy, l->y);
+           for(j=1;j<=steps;j++) {
+               //printf("%d\n", j);
+               double t = (double)j / (double)steps;
+               xyz[len*3+0] = lastx*(1-t)*(1-t) + 2*l->sx*(1-t)*t + l->x*t*t;
+               xyz[len*3+1] = lasty*(1-t)*(1-t) + 2*l->sy*(1-t)*t + l->y*t*t;
+               xyz[len*3+2] = z;
+               gluTessVertex(i->tesselator, &xyz[len*3], &xyz[len*3]);
+               len++;
+           }
+           //printf("%d\n", len);
+       } else {
+           xyz[len*3+0] = l->x;
+           xyz[len*3+1] = l->y;
+           xyz[len*3+2] = z;
+           gluTessVertex(i->tesselator, &xyz[len*3], &xyz[len*3]);
+           len++;
+       }
+       lastx = l->x;
+       lasty = l->y;
 
        l=l->next;
     }
@@ -203,6 +244,7 @@ void opengl_fill(struct _gfxdevice*dev, gfxline_t*line, gfxcolor_t*color)
 
 void opengl_fillbitmap(struct _gfxdevice*dev, gfxline_t*line, gfximage_t*img, gfxmatrix_t*matrix, gfxcxform_t*cxform)
 {
+    dbg("fillbitmap");
     internal_t*i = (internal_t*)dev->internal;
     char running = 0;
     int len = 0;
@@ -253,6 +295,7 @@ void opengl_fillbitmap(struct _gfxdevice*dev, gfxline_t*line, gfximage_t*img, gf
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
     glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
     
+    
     gluTessBeginPolygon(i->tesselator_tex, NULL);
     l = line;
     len = 0;
@@ -287,6 +330,7 @@ void opengl_fillbitmap(struct _gfxdevice*dev, gfxline_t*line, gfximage_t*img, gf
 
        l=l->next;
     }
+
     if(running) {
        running = 0;
        gluTessEndContour(i->tesselator_tex);
@@ -303,21 +347,20 @@ void opengl_fillgradient(struct _gfxdevice*dev, gfxline_t*line, gfxgradient_t*gr
     dbg("fillgradient");
 }
 
-void opengl_addfont(gfxdevice_t*dev, char*fontid, gfxfont_t*font)
+void opengl_addfont(gfxdevice_t*dev, gfxfont_t*font)
 {
     internal_t*i = (internal_t*)dev->internal;
     
     fontlist_t*last=0,*l = i->fontlist;
     while(l) {
        last = l;
-       if(!strcmp((char*)l->id, fontid)) {
+       if(!strcmp((char*)l->font->id, font->id)) {
            return; // we already know this font
        }
        l = l->next;
     }
     l = (fontlist_t*)rfx_calloc(sizeof(fontlist_t));
     l->font = font;
-    l->id = strdup(fontid);
     l->next = 0;
     if(last) {
        last->next = l;
@@ -326,26 +369,24 @@ void opengl_addfont(gfxdevice_t*dev, char*fontid, gfxfont_t*font)
     }
 }
 
-void opengl_drawchar(gfxdevice_t*dev, char*fontid, int glyphnr, gfxcolor_t*color, gfxmatrix_t*matrix)
+void opengl_drawchar(gfxdevice_t*dev, gfxfont_t*font, int glyphnr, gfxcolor_t*color, gfxmatrix_t*matrix)
 {
     internal_t*i = (internal_t*)dev->internal;
 
-    if(i->font && i->fontid && !strcmp(fontid, i->fontid)) {
+    if(i->font && i->font->id && !strcmp(font->id, i->font->id)) {
        // current font is correct
     } else {
        fontlist_t*l = i->fontlist;
        i->font = 0;
-       i->fontid = 0;
        while(l) {
-           if(!strcmp((char*)l->id, fontid)) {
+           if(!strcmp((char*)l->font->id, font->id)) {
                i->font = l->font;
-               i->fontid = l->id;
                break;
            }
            l = l->next;
        }
        if(i->font == 0) {
-           fprintf(stderr, "Unknown font id: %s", fontid);
+           fprintf(stderr, "Unknown font id: %s", font->id);
            return;
        }
     }
@@ -429,6 +470,7 @@ void gfxdevice_opengl_init(gfxdevice_t*dev)
     gluTessCallback(i->tesselator, GLU_TESS_VERTEX, (callbackfunction_t)vertexCallback);
     gluTessCallback(i->tesselator, GLU_TESS_BEGIN, (callbackfunction_t)beginCallback);
     gluTessCallback(i->tesselator, GLU_TESS_END, (callbackfunction_t)endCallback);
+    //gluTessCallback(i->tesselator, GLU_TESS_END, (callbackfunction_t)combineCallback);
     
     i->tesselator_tex = gluNewTess();
     gluTessCallback(i->tesselator_tex, GLU_TESS_ERROR, (callbackfunction_t)errorCallback);