added newline capability to swf_SetDefineText().
[swftools.git] / lib / modules / swftext.c
index b0d3de5..4b57c83 100644 (file)
@@ -101,7 +101,7 @@ int swf_FontIsBold(SWFFONT * f)
 
 static const int WRITEFONTID = 0x4e46; // font id for WriteFont and ReadFont
 
-int swf_FontEnumerate(SWF * swf, void (*FontCallback) (U16, U8 *))
+int swf_FontEnumerate(SWF * swf, void (*FontCallback) (void*, U16, U8 *), void*self)
 {
     int n;
     TAG *t;
@@ -129,7 +129,7 @@ int swf_FontEnumerate(SWF * swf, void (*FontCallback) (U16, U8 *))
                    s[l] = 0;
                }
 
-               (FontCallback) (id, s);
+               (FontCallback) (self, id, s);
 
                swf_RestoreTagPos(t);
            }
@@ -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));
        }
@@ -264,6 +263,8 @@ int swf_FontExtract_DefineFont2(int id, SWFFONT * font, TAG * tag)
     int t, glyphcount;
     int maxcode;
     int fid;
+    U32 offset_start;
+    U32 *offset;
     U8 flags1, flags2, namelen;
     swf_SaveTagPos(tag);
     swf_SetTagPos(tag, 0);
@@ -287,35 +288,44 @@ 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);
+
+    offset = rfx_calloc(sizeof(U32)*(glyphcount+1));
+    offset_start = tag->pos;
 
     if (flags1 & 8) {          // wide offsets
        for (t = 0; t < glyphcount; t++)
-           swf_GetU32(tag);    //offset[t]
+           offset[t] = swf_GetU32(tag);        //offset[t]
 
        if (glyphcount)         /* this _if_ is not in the specs */
-           swf_GetU32(tag);    // fontcodeoffset
+           offset[glyphcount] = swf_GetU32(tag);       // fontcodeoffset
+       else
+           offset[glyphcount] = tag->pos;
     } else {
        for (t = 0; t < glyphcount; t++)
-           swf_GetU16(tag);    //offset[t]
+           offset[t] = swf_GetU16(tag);        //offset[t]
 
        if (glyphcount)         /* this _if_ is not in the specs */
-           swf_GetU16(tag);    // fontcodeoffset
+           offset[glyphcount] = swf_GetU16(tag);       // fontcodeoffset
+       else
+           offset[glyphcount] = tag->pos;
     }
-    /* TODO: we should use the offset positions, not just
-             blindly read in shapes */
-    for (t = 0; t < glyphcount; t++)
+    for (t = 0; t < glyphcount; t++) {
+       swf_SetTagPos(tag, offset[t]+offset_start);
        swf_GetSimpleShape(tag, &(font->glyph[t].shape));
+    }
+
+    swf_SetTagPos(tag, offset[glyphcount]+offset_start);
+
+    free(offset);
 
     maxcode = 0;
     for (t = 0; t < glyphcount; t++) {
@@ -332,7 +342,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;
@@ -340,7 +350,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);
@@ -348,7 +358,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]);
@@ -357,9 +367,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);
@@ -384,7 +394,7 @@ int swf_FontExtract_DefineFont2(int id, SWFFONT * font, TAG * tag)
 static int
 swf_FontExtract_DefineTextCallback(int id, SWFFONT * f, TAG * t, int jobs,
                                   void (*callback) (void *self,
-                                                    int *chars, int *ypos, int nr, int fontid, int fontsize, int xstart, int ystart, RGBA * color), void *self)
+                                                    int *chars, int *xpos, int nr, int fontid, int fontsize, int xstart, int ystart, RGBA * color), void *self)
 {
     U16 cid;
     SRECT r;
@@ -421,6 +431,8 @@ swf_FontExtract_DefineTextCallback(int id, SWFFONT * f, TAG * t, int jobs,
                color.b = swf_GetU8(t);
                if (swf_GetTagID(t) == ST_DEFINETEXT2)
                    color.a = swf_GetU8(t);
+               else
+                   color.a = 255;
            }
            if (flags & TF_HASXOFFSET)
                x = swf_GetS16(t);
@@ -495,8 +507,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;
 
@@ -530,7 +541,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;
@@ -549,13 +560,13 @@ void swf_LayoutFree(SWFLAYOUT * l)
 {
     if (l) {
        if (l->kerning)
-           free(l->kerning);
+           rfx_free(l->kerning);
        l->kerning = NULL;
        if (l->bounds)
-           free(l->bounds);
+           rfx_free(l->bounds);
        l->bounds = NULL;
     }
-    free(l);
+    rfx_free(l);
 }
 
 
@@ -564,10 +575,12 @@ static void font_freeglyphnames(SWFFONT*f)
     if (f->glyphnames) {
        int t;
        for (t = 0; t < f->numchars; t++) {
-           if (f->glyphnames[t])
-               free(f->glyphnames[t]);
+           if (f->glyphnames[t]) {
+               rfx_free(f->glyphnames[t]);
+               f->glyphnames[t] = 0;
+           }
        }
-       free(f->glyphnames);
+       rfx_free(f->glyphnames);
        f->glyphnames = 0;
     }
 
@@ -576,9 +589,9 @@ static void font_freeusage(SWFFONT*f)
 {
     if (f->use) {
        if(f->use->chars) {
-           free(f->use->chars);f->use->chars = 0;
+           rfx_free(f->use->chars);f->use->chars = 0;
        }
-       free(f->use); f->use = 0;
+       rfx_free(f->use); f->use = 0;
     }
 }
 static void font_freelayout(SWFFONT*f)
@@ -591,12 +604,12 @@ static void font_freelayout(SWFFONT*f)
 static void font_freename(SWFFONT*f)
 {
     if (f->name) {
-       free(f->name);
+       rfx_free(f->name);
        f->name = 0;
     }
 }
 
-int swf_FontReduce(SWFFONT * f)
+int swf_FontReduce_old(SWFFONT * f)
 {
     int i, j;
     int max_unicode = 0;
@@ -639,6 +652,42 @@ int swf_FontReduce(SWFFONT * f)
     return j;
 }
 
+int swf_FontReduce(SWFFONT * f)
+{
+    int i;
+    int max_unicode = 0;
+    int max_glyph = 0;
+    if ((!f) || (!f->use) || f->use->is_reduced)
+       return -1;
+    
+    font_freelayout(f);
+    font_freeglyphnames(f);
+
+    for (i = 0; i < f->numchars; i++) {
+       if(!f->use->chars[i]) {
+           f->glyph2ascii[i] = 0;
+           if(f->glyph[i].shape) {
+               swf_ShapeFree(f->glyph[i].shape);
+               f->glyph[i].shape = 0;
+               f->glyph[i].advance = 0;
+           }
+       } else {
+           max_glyph = i+1;
+       }
+    }
+    for (i = 0; i < f->maxascii; i++) {
+       if(!f->use->chars[f->ascii2glyph[i]]) {
+           f->ascii2glyph[i] = -1;
+       } else {
+           max_unicode = i+1;
+       }
+    }
+    f->maxascii = max_unicode;
+    f->numchars = max_glyph;
+    font_freename(f);
+    return 0;
+}
+
 void swf_FontSort(SWFFONT * font)
 {
     int i, j, k;
@@ -647,7 +696,7 @@ void swf_FontSort(SWFFONT * font)
     if (!font)
        return;
     
-    newplace = malloc(sizeof(int) * font->numchars);
+    newplace = rfx_alloc(sizeof(int) * font->numchars);
 
     for (i = 0; i < font->numchars; i++) {
        newplace[i] = i;
@@ -685,7 +734,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;
     }
@@ -694,8 +743,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)
@@ -713,10 +762,9 @@ int swf_FontInitUsage(SWFFONT * f)
        fprintf(stderr, "Usage initialized twice");
        return -1;
     }
-    f->use = malloc(sizeof(FONTUSAGE));
+    f->use = rfx_alloc(sizeof(FONTUSAGE));
     f->use->is_reduced = 0;
-    f->use->chars = malloc(sizeof(f->use->chars[0]) * f->numchars);
-    memset(f->use->chars, 0, sizeof(f->use->chars[0]) * f->numchars);
+    f->use->chars = rfx_calloc(sizeof(f->use->chars[0]) * f->numchars);
     return 0;
 }
 
@@ -724,8 +772,8 @@ void swf_FontClearUsage(SWFFONT * f)
 {
     if (!f || !f->use)
        return;
-    free(f->use->chars); f->use->chars = 0;
-    free(f->use); f->use = 0;
+    rfx_free(f->use->chars); f->use->chars = 0;
+    rfx_free(f->use); f->use = 0;
 }
 
 int swf_FontUse(SWFFONT * f, U8 * s)
@@ -746,7 +794,7 @@ int swf_FontUseGlyph(SWFFONT * f, int glyph)
 {
     if (!f->use) 
        swf_FontInitUsage(f);
-    if(glyph < 0 || glyph > f->numchars)
+    if(glyph < 0 || glyph >= f->numchars)
        return -1;
     f->use->chars[glyph] = 1;
     return 0;
@@ -754,7 +802,7 @@ int swf_FontUseGlyph(SWFFONT * f, int glyph)
 
 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))
@@ -782,7 +830,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;
 }
 
@@ -910,14 +958,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)
@@ -983,15 +1030,15 @@ void swf_FontFree(SWFFONT * f)
                swf_ShapeFree(f->glyph[i].shape);
                f->glyph[i].shape = NULL;
            }
-       free(f->glyph);
+       rfx_free(f->glyph);
        f->glyph = NULL;
     }
     if (f->ascii2glyph) {
-       free(f->ascii2glyph);
+       rfx_free(f->ascii2glyph);
        f->ascii2glyph = NULL;
     }
     if (f->glyph2ascii) {
-       free(f->glyph2ascii);
+       rfx_free(f->glyph2ascii);
        f->glyph2ascii = NULL;
     }
     font_freename(f);
@@ -999,7 +1046,7 @@ void swf_FontFree(SWFFONT * f)
     font_freeglyphnames(f);
     font_freeusage(f);
 
-    free(f);
+    rfx_free(f);
 }
 
 int swf_TextSetInfoRecord(TAG * t, SWFFONT * font, U16 size, RGBA * color, int dx, int dy)
@@ -1021,14 +1068,22 @@ int swf_TextSetInfoRecord(TAG * t, SWFFONT * font, U16 size, RGBA * color, int d
            swf_SetRGB(t, color);
     }
     if (dx) {
-       if(dx>32767 || dx<-32768)
-           fprintf(stderr, "Warning: Horizontal char position overflow: %d\n", dx);
-       swf_SetS16(t, dx);
+       if(dx != SET_TO_ZERO) {
+           if(dx>32767 || dx<-32768)
+               fprintf(stderr, "Warning: Horizontal char position overflow: %d\n", dx);
+           swf_SetS16(t, dx);
+       } else {
+           swf_SetS16(t, 0);
+       }
     }
     if (dy) {
-       if(dy>32767 || dy<-32768)
-           fprintf(stderr, "Warning: Vertical char position overflow: %d\n", dy);
-       swf_SetS16(t, dy);
+       if(dy != SET_TO_ZERO) {
+           if(dy>32767 || dy<-32768)
+               fprintf(stderr, "Warning: Vertical char position overflow: %d\n", dy);
+           swf_SetS16(t, dy);
+       } else {
+           swf_SetS16(t, 0);
+       }
     }
     if (font)
        swf_SetU16(t, size);
@@ -1106,6 +1161,11 @@ static int swf_TextSetCharRecord2(TAG * t, SWFFONT * font, U8 * s, int scale, U8
            swf_SetBits(t, g, gbits);
            swf_SetBits(t, ((((U32) font->glyph[g].advance) * scale) / 20) / 100, abits);
            l++;
+           /* We split into 127 characters per text field.
+              We could do 255, by the (formerly wrong) flash specification,
+              but some SWF parsing code out there still assumes that char blocks
+              are at max 127 characters, and it would save only a few bits.
+           */
            if (l == 0x7f)
                break;
        }
@@ -1158,24 +1218,32 @@ U32 swf_TextGetWidth(SWFFONT * font, U8 * s, int scale)
 
 SRECT swf_TextCalculateBBoxUTF8(SWFFONT * font, U8 * s, int scale)
 {
-    int pos = 0;
+    int xpos = 0;
+    int ypos = 0;
     SRECT r;
     swf_GetRect(0, &r);
     while (*s) {
        int c = readUTF8char(&s);
+       if(c==13 || c==10) {
+           if(s[0] == 10) {
+               s++;
+           }
+           xpos=0;
+           ypos+=font->layout->leading;
+           continue;
+       }
        if (c < font->maxascii) {
            int g = font->ascii2glyph[c];
            if (g >= 0) {
                SRECT rn = font->layout->bounds[g];
-               rn.xmin = (rn.xmin * scale) / 20 / 100 + pos;
-               rn.xmax = (rn.xmax * scale) / 20 / 100 + pos;
-               rn.ymin = (rn.ymin * scale) / 20 / 100;
-               rn.ymax = (rn.ymax * scale) / 20 / 100;
+               rn.xmin = (rn.xmin * scale) / 20 / 100 + xpos;
+               rn.xmax = (rn.xmax * scale) / 20 / 100 + xpos;
+               rn.ymin = (rn.ymin * scale) / 20 / 100 + ypos;
+               rn.ymax = (rn.ymax * scale) / 20 / 100 + ypos;
                swf_ExpandRect2(&r, &rn);
-               pos += (font->glyph[g].advance * scale) / 20 / 100;
+               xpos += (font->glyph[g].advance * scale) / 20 / 100;
            }
        }
-       c++;
     }
     return r;
 }
@@ -1414,10 +1482,14 @@ SRECT swf_SetDefineText(TAG * tag, SWFFONT * font, RGBA * rgb, char *text, int s
 {
     SRECT r;
     U8 gbits, abits;
-    U8 *c = (U8 *) text;
+    U8 *utext = (U8 *) strdup(text);
+    U8 *upos = utext;
+    int x = 0, y = 0;
     int pos = 0;
+    int ystep = 0;
     if (font->layout) {
        r = swf_TextCalculateBBoxUTF8(font, text, scale * 20);
+       ystep = font->layout->leading;
     } else {
        fprintf(stderr, "No layout information- can't compute text bbox accurately");
        /* Hm, without layout information, we can't compute a bounding
@@ -1427,6 +1499,7 @@ SRECT swf_SetDefineText(TAG * tag, SWFFONT * font, RGBA * rgb, char *text, int s
         */
        r.xmin = r.ymin = 0;
        r.xmax = r.ymax = 1024 * 20;
+       ystep = 100;
     }
 
     swf_SetRect(tag, &r);
@@ -1443,17 +1516,45 @@ SRECT swf_SetDefineText(TAG * tag, SWFFONT * font, RGBA * rgb, char *text, int s
     swf_SetU8(tag, gbits);
     swf_SetU8(tag, abits);
 
-    /* now set the text params- notice that a font size of
-       1024 means that the glyphs will be displayed exactly
-       as they would be in/with a defineshape. (Try to find
-       *that* in the flash specs)
-     */
-    swf_TextSetInfoRecord(tag, font, (scale * 1024) / 100, rgb, 0, 0); //scale
+    while(*upos) {
+       U8*next = upos;
+       int count = 0;
+       
+       swf_TextSetInfoRecord(tag, font, (scale * 1024) / 100, rgb, x, y);      //scale
+       x = 0;
+
+       while(*next && *next!=13 && *next!=10 && count<127) {
+           readUTF8char(&next);
+           count++;
+       }
+       if(next[0] == 13 || next[0] == 10) {
+           x = SET_TO_ZERO;
+           y += ystep;
+       }
+
+       if(next[0] == 13 && next[1] == 10)
+           next++;
+       
+       if(next[0] == 13 || next[0] == 10) {
+           *next = 0;
+           next++;
+       }
 
-    /* set the actual text- notice that we just pass our scale
-       parameter over, as TextSetCharRecord calculates with 
-       percent, too */
-    swf_TextSetCharRecordUTF8(tag, font, text, scale * 20, gbits, abits);
+       /* now set the text params- notice that a font size of
+          1024 means that the glyphs will be displayed exactly
+          as they would be in/with a defineshape. (Try to find
+          *that* in the flash specs)
+        */
+       /* set the actual text- notice that we just pass our scale
+          parameter over, as TextSetCharRecord calculates with 
+          percent, too */
+       swf_TextSetCharRecordUTF8(tag, font, upos, scale * 20, gbits, abits);
+
+       upos= next;
+
+       printf("%s\n", upos);
+    }
+    free(utext);
 
     swf_SetU8(tag, 0);
     return r;
@@ -1468,9 +1569,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;