win32 compile fixes
[swftools.git] / lib / modules / swftext.c
index 1a9b59f..53abace 100644 (file)
@@ -1,13 +1,13 @@
 /* swftext.c
 
    Text and font routines
-      
+
    Extension module for the rfxswf library.
    Part of the swftools package.
 
    Copyright (c) 2001 Rainer Böhme <rfxswf@reflex-studio.de>
    Copyright (c) 2003,2004 Matthias Kramm
+
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
@@ -22,7 +22,7 @@
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
 
-static U32 readUTF8char(U8 ** text)
+U32 readUTF8char(U8 ** text)
 {
     U32 c = 0;
     if (!(*(*text) & 0x80))
@@ -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) (void*, U16, U8 *, void*self), void*self)
+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) (void*, U16, U8 *, void*se
                    s[l] = 0;
                }
 
-               (FontCallback) (self, id, s, self);
+               (FontCallback) (self, id, s);
 
                swf_RestoreTagPos(t);
            }
@@ -157,7 +157,7 @@ int swf_FontExtract_DefineFont(int id, SWFFONT * f, TAG * t)
        of = swf_GetU16(t);
        n = of / 2;
        f->numchars = n;
-       f->glyph = rfx_calloc(sizeof(SWFGLYPH) * n);
+       f->glyph = (SWFGLYPH*)rfx_calloc(sizeof(SWFGLYPH) * n);
 
        for (i = 1; i < n; i++)
            swf_GetU16(t);
@@ -237,8 +237,6 @@ int swf_FontExtract_DefineFontInfo(int id, SWFFONT * f, TAG * t)
 int swf_FontExtract_GlyphNames(int id, SWFFONT * f, TAG * tag)
 {
     U16 fid;
-    U16 maxcode;
-    U8 flags;
     swf_SaveTagPos(tag);
     swf_SetTagPos(tag, 0);
 
@@ -247,7 +245,7 @@ int swf_FontExtract_GlyphNames(int id, SWFFONT * f, TAG * tag)
     if (fid == id) {
        int num = swf_GetU16(tag);
        int t;
-       f->glyphnames = rfx_alloc(sizeof(char *) * num);
+       f->glyphnames = (char**)rfx_alloc(sizeof(char *) * num);
        for (t = 0; t < num; t++) {
            f->glyphnames[t] = strdup(swf_GetString(tag));
        }
@@ -263,6 +261,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);
@@ -296,23 +296,34 @@ int swf_FontExtract_DefineFont2(int id, SWFFONT * font, TAG * tag)
     font->glyph = (SWFGLYPH *) rfx_calloc(sizeof(SWFGLYPH) * glyphcount);
     font->glyph2ascii = (U16 *) rfx_calloc(sizeof(U16) * glyphcount);
 
+    offset = (U32*)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++) {
@@ -345,7 +356,7 @@ int swf_FontExtract_DefineFont2(int id, SWFFONT * font, TAG * tag)
            S16 advance = swf_GetS16(tag);
            font->glyph[t].advance = advance;
        }
-       font->layout->bounds = rfx_alloc(glyphcount * sizeof(SRECT));
+       font->layout->bounds = (SRECT*)rfx_alloc(glyphcount * sizeof(SRECT));
        for (t = 0; t < glyphcount; t++) {
            swf_ResetReadBits(tag);
            swf_GetRect(tag, &font->layout->bounds[t]);
@@ -356,7 +367,7 @@ int swf_FontExtract_DefineFont2(int id, SWFFONT * font, TAG * tag)
 
        font->layout->kerning = (SWFKERNING *) rfx_alloc(sizeof(SWFKERNING) * kerningcount);
        if (kerningcount) {
-           font->layout->kerning = rfx_alloc(sizeof(*font->layout->kerning) * kerningcount);
+           font->layout->kerning = (SWFKERNING*)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);
@@ -387,7 +398,7 @@ swf_FontExtract_DefineTextCallback(int id, SWFFONT * f, TAG * t, int jobs,
     SRECT r;
     MATRIX m;
     U8 gbits, abits;
-    int fid = 0;
+    int fid = -1;
     RGBA color;
     int x = 0, y = 0;
     int fontsize = 0;
@@ -418,6 +429,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);
@@ -444,20 +457,14 @@ swf_FontExtract_DefineTextCallback(int id, SWFFONT * f, TAG * t, int jobs,
                adv = swf_GetBits(t, abits);
                xpos += adv;
 
-               // <deprecated>
                if (id == fid) {
                    if (jobs & FEDTJ_PRINT) {
                        int code = f->glyph2ascii[glyph];
-                       printf("%c", code);
+                       printf("%lc", code);
                    }
                    if (jobs & FEDTJ_MODIFY)
                        f->glyph[glyph].advance = adv * 20;     //?
-               } else {
-                   if (jobs & FEDTJ_PRINT) {
-                       printf("?");
-                   }
                }
-               // </deprecated>
 
                buf[i] = glyph;
            }
@@ -557,16 +564,20 @@ void swf_LayoutFree(SWFLAYOUT * 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]);
+    if (f->glyphnames)
+    {
+        int t;
+        for (t = 0; t < f->numchars; t++)
+        {
+            if (f->glyphnames[t])
+            {
+                rfx_free(f->glyphnames[t]);
+                f->glyphnames[t] = 0;
+            }
+        }
+        rfx_free(f->glyphnames);
+        f->glyphnames = 0;
        }
-       rfx_free(f->glyphnames);
-       f->glyphnames = 0;
-    }
-
 }
 static void font_freeusage(SWFFONT*f)
 {
@@ -592,7 +603,7 @@ static void font_freename(SWFFONT*f)
     }
 }
 
-int swf_FontReduce(SWFFONT * f)
+int swf_FontReduce_old(SWFFONT * f)
 {
     int i, j;
     int max_unicode = 0;
@@ -635,15 +646,106 @@ int swf_FontReduce(SWFFONT * f)
     return j;
 }
 
+int swf_FontReduce_swfc(SWFFONT * f)
+{
+    int i, j;
+    int max_unicode = 0;
+    if ((!f) || (!f->use) || f->use->is_reduced)
+       return -1;
+
+    font_freeglyphnames(f);
+
+    j = 0;
+    for (i = 0; i < f->numchars; i++) {
+       if (f->glyph[i].shape && f->use->chars[i]) {
+           f->glyph2ascii[j] = f->glyph2ascii[i];
+           if (f->layout)
+               f->layout->bounds[j] = f->layout->bounds[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->glyph[i].shape = 0;
+               f->glyph[i].advance = 0;
+           }
+           f->use->chars[i] = -1;
+       }
+    }
+    f->use->used_glyphs = j;
+    for (i = 0; i < f->maxascii; i++) {
+       if(f->ascii2glyph[i] > -1) {
+           if (f->use->chars[f->ascii2glyph[i]]<0) {
+               f->use->chars[f->ascii2glyph[i]] = 0;
+               f->ascii2glyph[i] = -1;
+           } else {
+               f->ascii2glyph[i] = f->use->chars[f->ascii2glyph[i]];
+               f->use->chars[f->ascii2glyph[i]] = 1;
+               max_unicode = i + 1;
+           }
+       }
+    }
+    f->maxascii = max_unicode;
+    f->use->is_reduced = 1;
+    f->numchars = j;
+    font_freename(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);
+
+    f->use->used_glyphs= 0;
+    for (i = 0; i < f->numchars; i++) {
+       if(!f->use->chars[i]) {
+           if(f->glyph2ascii) {
+               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;
+           }
+//         f->use->used_glyphs++;
+       } else {
+           f->use->used_glyphs++;
+           max_glyph = i+1;
+       }
+    }
+    for (i = 0; i < f->maxascii; i++) {
+       if(f->ascii2glyph[i] > -1 && !f->use->chars[f->ascii2glyph[i]]) {
+           if(f->ascii2glyph) {
+               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;
+    int i, j;
     int *newplace;
     int *newpos;
     if (!font)
        return;
-    
-    newplace = rfx_alloc(sizeof(int) * font->numchars);
+
+    newplace = (int*)rfx_alloc(sizeof(int) * font->numchars);
 
     for (i = 0; i < font->numchars; i++) {
        newplace[i] = i;
@@ -681,7 +783,7 @@ void swf_FontSort(SWFFONT * font)
                }
            }
        }
-    newpos = rfx_alloc(sizeof(int) * font->numchars);
+    newpos = (int*)rfx_alloc(sizeof(int) * font->numchars);
     for (i = 0; i < font->numchars; i++) {
        newpos[newplace[i]] = i;
     }
@@ -709,9 +811,10 @@ int swf_FontInitUsage(SWFFONT * f)
        fprintf(stderr, "Usage initialized twice");
        return -1;
     }
-    f->use = rfx_alloc(sizeof(FONTUSAGE));
+    f->use = (FONTUSAGE*)rfx_alloc(sizeof(FONTUSAGE));
     f->use->is_reduced = 0;
-    f->use->chars = rfx_calloc(sizeof(f->use->chars[0]) * f->numchars);
+    f->use->used_glyphs = 0;
+    f->use->chars = (int*)rfx_calloc(sizeof(f->use->chars[0]) * f->numchars);
     return 0;
 }
 
@@ -725,24 +828,50 @@ void swf_FontClearUsage(SWFFONT * f)
 
 int swf_FontUse(SWFFONT * f, U8 * s)
 {
-    if (!f->use) 
-       swf_FontInitUsage(f);
     if( (!s))
        return -1;
     while (*s) {
        if(*s < f->maxascii && f->ascii2glyph[*s]>=0)
-           f->use->chars[f->ascii2glyph[*s]] = 1;
+           swf_FontUseGlyph(f, f->ascii2glyph[*s]);
        s++;
     }
     return 0;
 }
 
+int swf_FontUseUTF8(SWFFONT * f, U8 * s)
+{
+    if( (!s))
+       return -1;
+    int ascii;
+    while (*s)
+    {
+       ascii = readUTF8char(&s);
+       if(ascii < f->maxascii && f->ascii2glyph[ascii]>=0)
+           swf_FontUseGlyph(f, f->ascii2glyph[ascii]);
+    }
+    return 0;
+}
+
+int swf_FontUseAll(SWFFONT* f)
+{
+    int i;
+
+    if (!f->use)
+       swf_FontInitUsage(f);
+    for (i = 0; i < f->numchars; i++)
+       f->use->chars[i] = 1;
+    f->use->used_glyphs = f->numchars;
+    return 0;
+}
+
 int swf_FontUseGlyph(SWFFONT * f, int glyph)
 {
-    if (!f->use) 
+    if (!f->use)
        swf_FontInitUsage(f);
-    if(glyph < 0 || glyph > f->numchars)
+    if(glyph < 0 || glyph >= f->numchars)
        return -1;
+    if(!f->use->chars[glyph])
+       f->use->used_glyphs++;
     f->use->chars[glyph] = 1;
     return 0;
 }
@@ -787,7 +916,7 @@ static inline int fontSize(SWFFONT * font)
     int size = 0;
     for (t = 0; t < font->numchars; t++) {
        int l = 0;
-       if(font->glyph[t].shape) 
+       if(font->glyph[t].shape)
            l = (font->glyph[t].shape->bitlen + 7) / 8;
        else
            l = 8;
@@ -801,7 +930,6 @@ int swf_FontSetDefine2(TAG * tag, SWFFONT * f)
     U8 flags = 0;
     int t;
     int pos;
-    int pos2;
     swf_SetU16(tag, f->id);
 
     if (f->layout) flags |= 128;               // haslayout
@@ -828,8 +956,8 @@ int swf_FontSetDefine2(TAG * tag, SWFFONT * f)
     swf_SetU8(tag, 0);         //reserved flags
     if (f->name) {
        /* font name */
-       swf_SetU8(tag, strlen(f->name));
-       swf_SetBlock(tag, f->name, strlen(f->name));
+       swf_SetU8(tag, strlen((const char*)f->name));
+       swf_SetBlock(tag, f->name, strlen((const char*)f->name));
     } else {
        /* font name (="") */
        swf_SetU8(tag, 0);
@@ -870,14 +998,22 @@ int swf_FontSetDefine2(TAG * tag, SWFFONT * f)
 
 
     /* font code table */
-    if (flags & 4) {           /* wide codes */
-       for (t = 0; t < f->numchars; t++) {
-           swf_SetU16(tag, f->glyph2ascii[t]);
+    for (t = 0; t < f->numchars; t++) {
+       if (flags & 4) {                /* wide codes */
+           if(f->glyph2ascii[t]) {
+               swf_SetU16(tag, f->glyph2ascii[t]);
+           } else {
+               swf_SetU16(tag, 0);
+           }
+       } else {
+           if(f->glyph2ascii[t]) {
+               swf_SetU8(tag, f->glyph2ascii[t]);
+           } else {
+               swf_SetU8(tag, 0);
+           }
        }
-    } else {
-       for (t = 0; t < f->numchars; t++)
-           swf_SetU8(tag, f->glyph2ascii[t]);
     }
+
     if (f->layout) {
        swf_SetU16(tag, f->layout->ascent);
        swf_SetU16(tag, f->layout->descent);
@@ -923,7 +1059,7 @@ int swf_FontSetInfo(TAG * t, SWFFONT * f)
        return -1;
     swf_ResetWriteBits(t);
     swf_SetU16(t, f->id);
-    l = f->name ? strlen(f->name) : 0;
+    l = f->name ? strlen((const char *)f->name) : 0;
     if (l > 255)
        l = 255;
     swf_SetU8(t, l);
@@ -947,7 +1083,7 @@ int swf_FontSetInfo(TAG * t, SWFFONT * f)
 
     for (i = 0; i < f->numchars; i++) {
        if (f->glyph[i].shape) {
-           int g2a = f->glyph2ascii[i];
+           int g2a = f->glyph2ascii?f->glyph2ascii[i]:0;
            wide ? swf_SetU16(t, g2a) : swf_SetU8(t, g2a);
        }
     }
@@ -969,24 +1105,28 @@ void swf_FontFree(SWFFONT * f)
 {
     int i;
     if (!f)
-       return;
+        return;
 
-    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;
-           }
-       rfx_free(f->glyph);
-       f->glyph = 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;
+            }
+            rfx_free(f->glyph);
+            f->glyph = NULL;
     }
-    if (f->ascii2glyph) {
-       rfx_free(f->ascii2glyph);
-       f->ascii2glyph = NULL;
+    if (f->ascii2glyph)
+    {
+        rfx_free(f->ascii2glyph);
+        f->ascii2glyph = NULL;
     }
-    if (f->glyph2ascii) {
-       rfx_free(f->glyph2ascii);
-       f->glyph2ascii = NULL;
+    if (f->glyph2ascii)
+    {
+        rfx_free(f->glyph2ascii);
+        f->glyph2ascii = NULL;
     }
     font_freename(f);
     font_freelayout(f);
@@ -1108,6 +1248,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;
        }
@@ -1166,6 +1311,14 @@ SRECT swf_TextCalculateBBoxUTF8(SWFFONT * font, U8 * s, int scale)
     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) {
@@ -1178,7 +1331,6 @@ SRECT swf_TextCalculateBBoxUTF8(SWFFONT * font, U8 * s, int scale)
                xpos += (font->glyph[g].advance * scale) / 20 / 100;
            }
        }
-       c++;
     }
     return r;
 }
@@ -1217,7 +1369,7 @@ void swf_WriteFont(SWFFONT * font, char *filename)
     int storeGlyphNames = 1;
 
     if (font->layout)
-       useDefineFont2 = 1;     /* the only thing new in definefont2 
+       useDefineFont2 = 1;     /* the only thing new in definefont2
                                   is layout information. */
 
     font->id = WRITEFONTID;    //"FN"
@@ -1257,9 +1409,9 @@ void swf_WriteFont(SWFFONT * font, char *filename)
        swf_SetU16(t, font->numchars);
        for (c = 0; c < font->numchars; c++) {
            if (font->glyphnames[c])
-               swf_SetString(t, font->glyphnames[c]);
+               swf_SetString(t, (U8*)font->glyphnames[c]);
            else
-               swf_SetString(t, "");
+               swf_SetString(t, (U8*)"");
        }
     }
 
@@ -1408,19 +1560,23 @@ void swf_SetEditText(TAG * tag, U16 flags, SRECT r, char *text, RGBA * color, in
        swf_SetU16(tag, layout->indent);        //indent
        swf_SetU16(tag, layout->leading);       //leading
     }
-    swf_SetString(tag, variable);
+    swf_SetString(tag, (U8*)variable);
     if (flags & ET_HASTEXT)
-       swf_SetString(tag, text);
+       swf_SetString(tag, (U8*)text);
 }
 
 SRECT swf_SetDefineText(TAG * tag, SWFFONT * font, RGBA * rgb, char *text, int scale)
 {
     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);
+       r = swf_TextCalculateBBoxUTF8(font, (U8*)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
@@ -1430,6 +1586,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);
@@ -1442,21 +1599,47 @@ SRECT swf_SetDefineText(TAG * tag, SWFFONT * font, RGBA * rgb, char *text, int s
      */
     swf_SetMatrix(tag, 0);
 
-    swf_TextCountBitsUTF8(font, text, scale * 20, &gbits, &abits);
+    swf_TextCountBitsUTF8(font, (U8*)text, scale * 20, &gbits, &abits);
     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;
 
-    /* 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);
+       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++;
+       }
+
+       /* 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;
+    }
+    free(utext);
 
     swf_SetU8(tag, 0);
     return r;