changed from malloc to rfx_alloc.
[swftools.git] / lib / modules / swftext.c
index f9840ed..87c278a 100644 (file)
@@ -157,8 +157,7 @@ int swf_FontExtract_DefineFont(int id, SWFFONT * f, TAG * t)
        of = swf_GetU16(t);
        n = of / 2;
        f->numchars = n;
-       f->glyph = malloc(sizeof(SWFGLYPH) * n);
-       memset(f->glyph, 0, sizeof(SWFGLYPH) * n);
+       f->glyph = rfx_calloc(sizeof(SWFGLYPH) * n);
 
        for (i = 1; i < n; i++)
            swf_GetU16(t);
@@ -191,9 +190,9 @@ int swf_FontExtract_DefineFontInfo(int id, SWFFONT * f, TAG * t)
        }
 
        if (f->name)
-           free(f->name);
+           rfx_free(f->name);
 
-       f->name = (U8 *) malloc(l + 1);
+       f->name = (U8 *) rfx_alloc(l + 1);
        swf_GetBlock(t, f->name, l);
        f->name[l] = 0;
 
@@ -213,7 +212,7 @@ int swf_FontExtract_DefineFontInfo(int id, SWFFONT * f, TAG * t)
            f->language = swf_GetU8(t);
        }
 
-       f->glyph2ascii = (U16 *) malloc(sizeof(U16) * f->numchars);
+       f->glyph2ascii = (U16 *) rfx_alloc(sizeof(U16) * f->numchars);
        maxcode = 0;
        for (i = 0; i < f->numchars; i++) {
            f->glyph2ascii[i] = ((flags & FF_WIDECODES) ? swf_GetU16(t) : swf_GetU8(t));
@@ -224,7 +223,7 @@ int swf_FontExtract_DefineFontInfo(int id, SWFFONT * f, TAG * t)
        if (maxcode < 256)
            maxcode = 256;
        f->maxascii = maxcode;
-       f->ascii2glyph = (int *) malloc(sizeof(int) * maxcode);
+       f->ascii2glyph = (int *) rfx_alloc(sizeof(int) * maxcode);
        memset(f->ascii2glyph, -1, sizeof(int) * maxcode);
 
        for (i = 0; i < f->numchars; i++)
@@ -248,7 +247,7 @@ int swf_FontExtract_GlyphNames(int id, SWFFONT * f, TAG * tag)
     if (fid == id) {
        int num = swf_GetU16(tag);
        int t;
-       f->glyphnames = malloc(sizeof(char *) * num);
+       f->glyphnames = rfx_alloc(sizeof(char *) * num);
        for (t = 0; t < num; t++) {
            f->glyphnames[t] = strdup(swf_GetString(tag));
        }
@@ -287,17 +286,15 @@ int swf_FontExtract_DefineFont2(int id, SWFFONT * font, TAG * tag)
        font->encoding |= FONT_ENCODING_SHIFTJIS;
 
     namelen = swf_GetU8(tag);
-    font->name = (U8 *) malloc(namelen + 1);
+    font->name = (U8 *) rfx_alloc(namelen + 1);
     font->name[namelen] = 0;
     swf_GetBlock(tag, font->name, namelen);
     font->version = 2;
     glyphcount = swf_GetU16(tag);
     font->numchars = glyphcount;
 
-    font->glyph = (SWFGLYPH *) malloc(sizeof(SWFGLYPH) * glyphcount);
-    memset(font->glyph, 0, sizeof(SWFGLYPH) * glyphcount);
-    font->glyph2ascii = (U16 *) malloc(sizeof(U16) * glyphcount);
-    memset(font->glyph2ascii, 0, sizeof(U16) * glyphcount);
+    font->glyph = (SWFGLYPH *) rfx_calloc(sizeof(SWFGLYPH) * glyphcount);
+    font->glyph2ascii = (U16 *) rfx_calloc(sizeof(U16) * glyphcount);
 
     if (flags1 & 8) {          // wide offsets
        for (t = 0; t < glyphcount; t++)
@@ -312,6 +309,8 @@ int swf_FontExtract_DefineFont2(int id, SWFFONT * font, TAG * tag)
        if (glyphcount)         /* this _if_ is not in the specs */
            swf_GetU16(tag);    // fontcodeoffset
     }
+    /* TODO: we should use the offset positions, not just
+             blindly read in shapes */
     for (t = 0; t < glyphcount; t++)
        swf_GetSimpleShape(tag, &(font->glyph[t].shape));
 
@@ -330,7 +329,7 @@ int swf_FontExtract_DefineFont2(int id, SWFFONT * font, TAG * tag)
     if (maxcode < 256)
        maxcode = 256;
     font->maxascii = maxcode;
-    font->ascii2glyph = (int *) malloc(sizeof(int) * maxcode);
+    font->ascii2glyph = (int *) rfx_alloc(sizeof(int) * maxcode);
     memset(font->ascii2glyph, -1, sizeof(int) * maxcode);
     for (t = 0; t < glyphcount; t++) {
        font->ascii2glyph[font->glyph2ascii[t]] = t;
@@ -338,7 +337,7 @@ int swf_FontExtract_DefineFont2(int id, SWFFONT * font, TAG * tag)
 
     if (flags1 & 128) {                // has layout
        U16 kerningcount;
-       font->layout = (SWFLAYOUT *) malloc(sizeof(SWFLAYOUT));
+       font->layout = (SWFLAYOUT *) rfx_alloc(sizeof(SWFLAYOUT));
        font->layout->ascent = swf_GetU16(tag);
        font->layout->descent = swf_GetU16(tag);
        font->layout->leading = swf_GetU16(tag);
@@ -346,7 +345,7 @@ int swf_FontExtract_DefineFont2(int id, SWFFONT * font, TAG * tag)
            S16 advance = swf_GetS16(tag);
            font->glyph[t].advance = advance;
        }
-       font->layout->bounds = malloc(glyphcount * sizeof(SRECT));
+       font->layout->bounds = rfx_alloc(glyphcount * sizeof(SRECT));
        for (t = 0; t < glyphcount; t++) {
            swf_ResetReadBits(tag);
            swf_GetRect(tag, &font->layout->bounds[t]);
@@ -355,9 +354,9 @@ int swf_FontExtract_DefineFont2(int id, SWFFONT * font, TAG * tag)
        kerningcount = swf_GetU16(tag);
        font->layout->kerningcount = kerningcount;
 
-       font->layout->kerning = (SWFKERNING *) malloc(sizeof(SWFKERNING) * kerningcount);
+       font->layout->kerning = (SWFKERNING *) rfx_alloc(sizeof(SWFKERNING) * kerningcount);
        if (kerningcount) {
-           font->layout->kerning = malloc(sizeof(*font->layout->kerning) * kerningcount);
+           font->layout->kerning = rfx_alloc(sizeof(*font->layout->kerning) * kerningcount);
            for (t = 0; t < kerningcount; t++) {
                if (flags1 & 4) {       // wide codes
                    font->layout->kerning[t].char1 = swf_GetU16(tag);
@@ -493,8 +492,7 @@ int swf_FontExtract(SWF * swf, int id, SWFFONT * *font)
     if ((!swf) || (!font))
        return -1;
 
-    f = (SWFFONT *) malloc(sizeof(SWFFONT));
-    memset(f, 0x00, sizeof(SWFFONT));
+    f = (SWFFONT *) rfx_calloc(sizeof(SWFFONT));
 
     t = swf->firstTag;
 
@@ -528,7 +526,7 @@ int swf_FontExtract(SWF * swf, int id, SWFFONT * *font)
        t = swf_NextTag(t);
     }
     if (f->id != id) {
-       free(f);
+       rfx_free(f);
        f = 0;
     }
     font[0] = f;
@@ -543,43 +541,109 @@ int swf_FontSetID(SWFFONT * f, U16 id)
     return 0;
 }
 
-int swf_FontReduce(SWFFONT * f, FONTUSAGE * use)
+void swf_LayoutFree(SWFLAYOUT * l)
+{
+    if (l) {
+       if (l->kerning)
+           rfx_free(l->kerning);
+       l->kerning = NULL;
+       if (l->bounds)
+           rfx_free(l->bounds);
+       l->bounds = NULL;
+    }
+    rfx_free(l);
+}
+
+
+static void font_freeglyphnames(SWFFONT*f)
+{
+    if (f->glyphnames) {
+       int t;
+       for (t = 0; t < f->numchars; t++) {
+           if (f->glyphnames[t])
+               rfx_free(f->glyphnames[t]);
+       }
+       rfx_free(f->glyphnames);
+       f->glyphnames = 0;
+    }
+
+}
+static void font_freeusage(SWFFONT*f)
+{
+    if (f->use) {
+       if(f->use->chars) {
+           rfx_free(f->use->chars);f->use->chars = 0;
+       }
+       rfx_free(f->use); f->use = 0;
+    }
+}
+static void font_freelayout(SWFFONT*f)
+{
+    if (f->layout) {
+       swf_LayoutFree(f->layout);
+       f->layout = 0;
+    }
+}
+static void font_freename(SWFFONT*f)
+{
+    if (f->name) {
+       rfx_free(f->name);
+       f->name = 0;
+    }
+}
+
+int swf_FontReduce(SWFFONT * f)
 {
     int i, j;
-    if ((!f) || (!use))
+    int max_unicode = 0;
+    if ((!f) || (!f->use) || f->use->is_reduced)
        return -1;
 
-    /* TODO: layout, glyphnames */
     j = 0;
-    for (i = 0; i < f->numchars; i++)
-       if (f->glyph[i].shape) {
-           if (f->glyph2ascii[i] < f->maxascii && use->code[f->glyph2ascii[i]]) {
-               f->ascii2glyph[f->glyph2ascii[i]] = j;
-               f->glyph2ascii[j] = f->glyph2ascii[i];
-               f->glyph[j] = f->glyph[i];
-               j++;
-           } else {
+
+    for (i = 0; i < f->numchars; i++) {
+       if (f->glyph[i].shape && f->use->chars[i]) {
+           f->glyph2ascii[j] = f->glyph2ascii[i];
+           f->glyph[j] = f->glyph[i];
+           f->use->chars[i] = j;
+           j++;
+       } else {
+           f->glyph2ascii[i] = 0;
+           if(f->glyph[i].shape) {
                swf_ShapeFree(f->glyph[i].shape);
-               f->ascii2glyph[f->glyph2ascii[i]] = -1;
-               f->glyph2ascii[i] = 0;
-               f->glyph[i].shape = NULL;
+               f->glyph[i].shape = 0;
                f->glyph[i].advance = 0;
            }
-       } else
-           f->ascii2glyph[f->glyph2ascii[i]] = -1;
-
+           f->use->chars[i] = -1;
+           j++; //TODO: remove
+       }
+    }
+    for (i = 0; i < f->maxascii; i++) {
+       if(f->use->chars[f->ascii2glyph[i]]<0) {
+           f->ascii2glyph[i] = -1;
+       } else {
+           f->ascii2glyph[i] = f->use->chars[f->ascii2glyph[i]];
+           max_unicode = i;
+       }
+    }
+    f->maxascii = max_unicode;
+    f->use->is_reduced = 1;
     f->numchars = j;
-
+    font_freelayout(f);
+    font_freeglyphnames(f);
+    font_freename(f);
     return j;
 }
 
 void swf_FontSort(SWFFONT * font)
 {
-    if (!font)
-       return;
     int i, j, k;
-    int *newplace = malloc(sizeof(int) * font->numchars);
+    int *newplace;
     int *newpos;
+    if (!font)
+       return;
+    
+    newplace = rfx_alloc(sizeof(int) * font->numchars);
 
     for (i = 0; i < font->numchars; i++) {
        newplace[i] = i;
@@ -617,7 +681,7 @@ void swf_FontSort(SWFFONT * font)
                }
            }
        }
-    newpos = malloc(sizeof(int) * font->numchars);
+    newpos = rfx_alloc(sizeof(int) * font->numchars);
     for (i = 0; i < font->numchars; i++) {
        newpos[newplace[i]] = i;
     }
@@ -626,8 +690,8 @@ void swf_FontSort(SWFFONT * font)
            font->ascii2glyph[i] = newpos[font->ascii2glyph[i]];
     }
 
-    free(newpos);
-    free(newplace);
+    rfx_free(newpos);
+    rfx_free(newplace);
 }
 
 void swf_FontPrepareForEditText(SWFFONT * font)
@@ -637,36 +701,55 @@ void swf_FontPrepareForEditText(SWFFONT * font)
     swf_FontSort(font);
 }
 
-int swf_FontInitUsage(SWFFONT * f, FONTUSAGE * use)
+int swf_FontInitUsage(SWFFONT * f)
 {
-    if (!use)
+    if (!f)
+       return -1;
+    if(f->use) {
+       fprintf(stderr, "Usage initialized twice");
        return -1;
-    use->code = malloc(sizeof(use->code[0]) * f->maxascii);
-    memset(use->code, 0, sizeof(use->code[0]) * f->maxascii);
+    }
+    f->use = rfx_alloc(sizeof(FONTUSAGE));
+    f->use->is_reduced = 0;
+    f->use->chars = rfx_calloc(sizeof(f->use->chars[0]) * f->numchars);
     return 0;
 }
 
-void swf_FontClearUsage(SWFFONT * f, FONTUSAGE * use)
+void swf_FontClearUsage(SWFFONT * f)
 {
-    if (!use)
+    if (!f || !f->use)
        return;
-    free(use->code);
+    rfx_free(f->use->chars); f->use->chars = 0;
+    rfx_free(f->use); f->use = 0;
 }
 
-int swf_FontUse(SWFFONT * f, FONTUSAGE * use, U8 * s)
+int swf_FontUse(SWFFONT * f, U8 * s)
 {
-    if ((!use) || (!s))
+    if (!f->use) 
+       swf_FontInitUsage(f);
+    if( (!s))
        return -1;
-    while (s[0]) {
-       use->code[s[0]] = 1;
+    while (*s) {
+       if(*s < f->maxascii && f->ascii2glyph[*s]>=0)
+           f->use->chars[f->ascii2glyph[*s]] = 1;
        s++;
     }
     return 0;
 }
 
+int swf_FontUseGlyph(SWFFONT * f, int glyph)
+{
+    if (!f->use) 
+       swf_FontInitUsage(f);
+    if(glyph < 0 || glyph > f->numchars)
+       return -1;
+    f->use->chars[glyph] = 1;
+    return 0;
+}
+
 int swf_FontSetDefine(TAG * t, SWFFONT * f)
 {
-    U16 *ofs = (U16 *) malloc(f->numchars * 2);
+    U16 *ofs = (U16 *) rfx_alloc(f->numchars * 2);
     int p, i, j;
 
     if ((!t) || (!f))
@@ -694,7 +777,7 @@ int swf_FontSetDefine(TAG * t, SWFFONT * f)
            swf_SetSimpleShape(t, f->glyph[i].shape);
 
     swf_ResetWriteBits(t);
-    free(ofs);
+    rfx_free(ofs);
     return 0;
 }
 
@@ -703,7 +786,11 @@ static inline int fontSize(SWFFONT * font)
     int t;
     int size = 0;
     for (t = 0; t < font->numchars; t++) {
-       int l = (font->glyph[t].shape->bitlen + 7) / 8;
+       int l = 0;
+       if(font->glyph[t].shape) 
+           l = (font->glyph[t].shape->bitlen + 7) / 8;
+       else
+           l = 8;
        size += l + 1;
     }
     return size + (font->numchars + 1) * 2;
@@ -745,7 +832,7 @@ int swf_FontSetDefine2(TAG * tag, SWFFONT * f)
        swf_SetBlock(tag, f->name, strlen(f->name));
     } else {
        /* font name (="") */
-       swf_SetU8(tag, 0);      /*placeholder */
+       swf_SetU8(tag, 0);
     }
     /* number of glyphs */
     swf_SetU16(tag, f->numchars);
@@ -772,8 +859,13 @@ int swf_FontSetDefine2(TAG * tag, SWFFONT * f)
            tag->data[pos + t * 2] = (tag->len - pos);
            tag->data[pos + t * 2 + 1] = (tag->len - pos) >> 8;
        }
-       if (t < f->numchars)
-           swf_SetSimpleShape(tag, f->glyph[t].shape);
+       if (t < f->numchars) {
+           if(f->glyph[t].shape) {
+               swf_SetSimpleShape(tag, f->glyph[t].shape);
+           } else {
+               swf_SetU8(tag, 0); //non-edge(1) + edge flags(5)
+           }
+       }
     }
 
 
@@ -813,14 +905,13 @@ int swf_FontSetDefine2(TAG * tag, SWFFONT * f)
 
 void swf_FontAddLayout(SWFFONT * f, int ascent, int descent, int leading)
 {
-    f->layout = (SWFLAYOUT *) malloc(sizeof(SWFLAYOUT));
+    f->layout = (SWFLAYOUT *) rfx_alloc(sizeof(SWFLAYOUT));
     f->layout->ascent = ascent;
     f->layout->descent = descent;
     f->layout->leading = leading;
     f->layout->kerningcount = 0;
     f->layout->kerning = 0;
-    f->layout->bounds = (SRECT *) malloc(sizeof(SRECT) * f->numchars);
-    memset(f->layout->bounds, 0, sizeof(SRECT) * f->numchars);
+    f->layout->bounds = (SRECT *) rfx_calloc(sizeof(SRECT) * f->numchars);
 }
 
 int swf_FontSetInfo(TAG * t, SWFFONT * f)
@@ -874,59 +965,35 @@ int swf_TextPrintDefineText(TAG * t, SWFFONT * f)
     return 0;
 }
 
-void swf_LayoutFree(SWFLAYOUT * l)
-{
-    if (l) {
-       if (l->kerning)
-           free(l->kerning);
-       l->kerning = NULL;
-       if (l->bounds)
-           free(l->bounds);
-       l->bounds = NULL;
-    }
-    free(l);
-}
-
 void swf_FontFree(SWFFONT * f)
 {
-    if (f) {
-       int i;
+    int i;
+    if (!f)
+       return;
 
-       if (f->name)
-           free(f->name);
-       if (f->layout)
-           swf_LayoutFree(f->layout);
-
-       f->name = NULL;
-       f->layout = NULL;
-
-       if (f->glyph) {
-           for (i = 0; i < f->numchars; i++)
-               if (f->glyph[i].shape) {
-                   swf_ShapeFree(f->glyph[i].shape);
-                   f->glyph[i].shape = NULL;
-               }
-           free(f->glyph);
-           f->glyph = NULL;
-       }
-       if (f->ascii2glyph) {
-           free(f->ascii2glyph);
-           f->ascii2glyph = NULL;
-       }
-       if (f->glyph2ascii) {
-           free(f->glyph2ascii);
-           f->glyph2ascii = NULL;
-       }
-       if (f->glyphnames) {
-           int t;
-           for (t = 0; t < f->numchars; t++) {
-               if (f->glyphnames[t])
-                   free(f->glyphnames[t]);
+    if (f->glyph) {
+       for (i = 0; i < f->numchars; i++)
+           if (f->glyph[i].shape) {
+               swf_ShapeFree(f->glyph[i].shape);
+               f->glyph[i].shape = NULL;
            }
-           free(f->glyphnames);
-       }
+       rfx_free(f->glyph);
+       f->glyph = NULL;
     }
-    free(f);
+    if (f->ascii2glyph) {
+       rfx_free(f->ascii2glyph);
+       f->ascii2glyph = NULL;
+    }
+    if (f->glyph2ascii) {
+       rfx_free(f->glyph2ascii);
+       f->glyph2ascii = NULL;
+    }
+    font_freename(f);
+    font_freelayout(f);
+    font_freeglyphnames(f);
+    font_freeusage(f);
+
+    rfx_free(f);
 }
 
 int swf_TextSetInfoRecord(TAG * t, SWFFONT * font, U16 size, RGBA * color, int dx, int dy)
@@ -947,10 +1014,16 @@ int swf_TextSetInfoRecord(TAG * t, SWFFONT * font, U16 size, RGBA * color, int d
        else
            swf_SetRGB(t, color);
     }
-    if (dx)
+    if (dx) {
+       if(dx>32767 || dx<-32768)
+           fprintf(stderr, "Warning: Horizontal char position overflow: %d\n", dx);
        swf_SetS16(t, dx);
-    if (dy)
+    }
+    if (dy) {
+       if(dy>32767 || dy<-32768)
+           fprintf(stderr, "Warning: Vertical char position overflow: %d\n", dy);
        swf_SetS16(t, dy);
+    }
     if (font)
        swf_SetU16(t, size);
 
@@ -1108,7 +1181,7 @@ SWFFONT *swf_ReadFont(char *filename)
     SWF swf;
     if (!filename)
        return 0;
-    f = open(filename, O_RDONLY);
+    f = open(filename, O_RDONLY|O_BINARY);
 
     if (f < 0 || swf_ReadSWF(f, &swf) < 0) {
        fprintf(stderr, "%s is not a valid SWF font file or contains errors.\n", filename);
@@ -1281,7 +1354,7 @@ void swf_WriteFont(SWFFONT * font, char *filename)
 
     t = swf_InsertTag(t, ST_END);
 
-    f = open(filename, O_RDWR | O_CREAT | O_TRUNC, 0644);
+    f = open(filename, O_RDWR | O_CREAT | O_TRUNC | O_BINARY, 0644);
     if FAILED
        (swf_WriteSWF(f, &swf)) fprintf(stderr, "WriteSWF() failed in writeFont().\n");
     close(f);
@@ -1389,9 +1462,8 @@ void swf_FontCreateLayout(SWFFONT * f)
     if (!f->numchars)
        return;
 
-    f->layout = (SWFLAYOUT *) malloc(sizeof(SWFLAYOUT));
-    memset(f->layout, 0, sizeof(SWFLAYOUT));
-    f->layout->bounds = (SRECT *) malloc(f->numchars * sizeof(SRECT));
+    f->layout = (SWFLAYOUT *) rfx_calloc(sizeof(SWFLAYOUT));
+    f->layout->bounds = (SRECT *) rfx_alloc(f->numchars * sizeof(SRECT));
     f->layout->ascent = -32767;
     f->layout->descent = -32767;