+
+ if (f->layout) {
+ swf_SetU16(tag, f->layout->ascent);
+ swf_SetU16(tag, f->layout->descent);
+ swf_SetU16(tag, f->layout->leading);
+ for (t = 0; t < f->numchars; t++)
+ swf_SetU16(tag, f->glyph[t].advance);
+ for (t = 0; t < f->numchars; t++) {
+ swf_ResetWriteBits(tag);
+ swf_SetRect(tag, &f->layout->bounds[t]);
+ }
+ swf_SetU16(tag, f->layout->kerningcount);
+ for (t = 0; t < f->layout->kerningcount; t++) {
+ if (flags & 4) { /* wide codes */
+ swf_SetU16(tag, f->layout->kerning[t].char1);
+ swf_SetU16(tag, f->layout->kerning[t].char2);
+ } else {
+ swf_SetU8(tag, f->layout->kerning[t].char1);
+ swf_SetU8(tag, f->layout->kerning[t].char2);
+ }
+ swf_SetU16(tag, f->layout->kerning[t].adjustment);
+ }
+ }
+ return 0;
+}
+
+void swf_FontSetAlignZones(TAG*t, SWFFONT *f)
+{
+ swf_SetU16(t, f->id);
+ swf_SetU8(t, f->alignzone_flags);
+ int i;
+ for(i=0;i<f->numchars;i++) {
+ ALIGNZONE*a = &f->alignzones[i];
+ U8 flags = 0;
+ if((a->x & a->dx)!=0xffff)
+ flags |= 1;
+ if((a->y & a->dy)!=0xffff)
+ flags |= 2;
+ swf_SetU8(t, 2);
+ if(flags&1) swf_SetU16(t, a->x); else swf_SetU16(t, 0);
+ if(flags&2) swf_SetU16(t, a->y); else swf_SetU16(t, 0);
+ if((flags&1) && a->dx!=0xffff) swf_SetU16(t, a->dx); else swf_SetU16(t, 0);
+ if((flags&2) && a->dy!=0xffff) swf_SetU16(t, a->dy); else swf_SetU16(t, 0);
+ swf_SetU8(t, flags);
+ }
+}
+
+void swf_FontAddLayout(SWFFONT * f, int ascent, int descent, int leading)
+{
+ 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 *) rfx_calloc(sizeof(SRECT) * f->numchars);
+}
+
+int swf_FontSetInfo(TAG * t, SWFFONT * f)
+{
+ int l, i;
+ U8 wide = 0;
+ U8 flags = 0;
+ if ((!t) || (!f))
+ return -1;
+ swf_ResetWriteBits(t);
+ swf_SetU16(t, f->id);
+ l = f->name ? strlen((const char *)f->name) : 0;
+ if (l > 255)
+ l = 255;
+ swf_SetU8(t, l);
+ if (l)
+ swf_SetBlock(t, f->name, l);
+ if (f->numchars >= 256)
+ wide = 1;
+
+ if (f->style & FONT_STYLE_BOLD)
+ flags |= 2;
+ if (f->style & FONT_STYLE_ITALIC)
+ flags |= 4;
+ if (f->style & FONT_ENCODING_ANSI)
+ flags |= 8;
+ if (f->style & FONT_ENCODING_SHIFTJIS)
+ flags |= 16;
+ if (f->style & FONT_ENCODING_UNICODE)
+ flags |= 32;
+
+ swf_SetU8(t, (flags & 0xfe) | wide);
+
+ for (i = 0; i < f->numchars; i++) {
+ if (f->glyph[i].shape) {
+ int g2a = f->glyph2ascii?f->glyph2ascii[i]:0;
+ wide ? swf_SetU16(t, g2a) : swf_SetU8(t, g2a);
+ }
+ }
+
+ return 0;
+}
+
+int swf_TextPrintDefineText(TAG * t, SWFFONT * f)
+{
+ int id = swf_GetTagID(t);
+ if ((id == ST_DEFINETEXT) || (id == ST_DEFINETEXT2))
+ swf_FontExtract_DefineText(f->id, f, t, FEDTJ_PRINT);
+ else
+ return -1;
+ return 0;
+}
+
+void swf_FontFree(SWFFONT * f)
+{
+ int i;
+ if (!f)
+ 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->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 x, int y)
+{
+ U8 flags;
+ if (!t)
+ return -1;
+
+ flags = TF_TEXTCONTROL | (font ? TF_HASFONT : 0) | (color ? TF_HASCOLOR : 0) | (x ? TF_HASXOFFSET : 0)
+ | (y ? TF_HASYOFFSET : 0);
+
+ swf_SetU8(t, flags);
+ if (font)
+ swf_SetU16(t, font->id);
+ if (color) {
+ if (swf_GetTagID(t) == ST_DEFINETEXT2)
+ swf_SetRGBA(t, color);
+ else
+ swf_SetRGB(t, color);
+ }
+ if (x) {
+ if(x != SET_TO_ZERO) {
+ if(x>32767 || x<-32768)
+ fprintf(stderr, "Warning: Horizontal char position overflow: %d\n", x);
+ swf_SetS16(t, x);
+ } else {
+ swf_SetS16(t, 0);
+ }
+ }
+ if (y) {
+ if(y != SET_TO_ZERO) {
+ if(y>32767 || y<-32768)
+ fprintf(stderr, "Warning: Vertical char position overflow: %d\n", y);
+ swf_SetS16(t, y);
+ } else {
+ swf_SetS16(t, 0);
+ }
+ }
+ if (font)
+ swf_SetU16(t, size);
+
+ return 0;
+}
+
+static int swf_TextCountBits2(SWFFONT * font, U8 * s, int scale, U8 * gbits, U8 * abits, char *encoding)
+{
+ U16 g, a;
+ char utf8 = 0;
+ if ((!s) || (!font) || ((!gbits) && (!abits)) || (!font->ascii2glyph))
+ return -1;
+ g = a = 0;
+
+ if (!strcmp(encoding, "UTF8"))
+ utf8 = 1;
+ else if (!strcmp(encoding, "iso-8859-1"))
+ utf8 = 0;
+ else
+ fprintf(stderr, "Unknown encoding: %s", encoding);
+
+ while (*s) {
+ int glyph = -1, c;
+
+ if (!utf8)
+ c = *s++;
+ else
+ c = readUTF8char(&s);
+
+ if (c < font->maxascii)
+ glyph = font->ascii2glyph[c];
+ if (glyph >= 0) {
+ g = swf_CountUBits(glyph, g);
+ a = swf_CountBits(((((U32) font->glyph[glyph].advance) * scale) / 20) / 100, a);
+ }
+ }
+
+ if (gbits)
+ gbits[0] = (U8) g;
+ if (abits)
+ abits[0] = (U8) a;
+ return 0;
+}
+
+static int swf_TextSetCharRecord2(TAG * t, SWFFONT * font, U8 * s, int scale, U8 gbits, U8 abits, char *encoding)
+{
+ int l = 0, pos;
+ char utf8 = 0;
+
+ if ((!t) || (!font) || (!s) || (!font->ascii2glyph))
+ return -1;
+
+ if (!strcmp(encoding, "UTF8"))
+ utf8 = 1;
+ else if (!strcmp(encoding, "iso-8859-1"))
+ utf8 = 0;
+ else
+ fprintf(stderr, "Unknown encoding: %s", encoding);
+
+ pos = t->len;
+ swf_SetU8(t, l); //placeholder
+
+ while (*s) {
+ int g = -1, c;
+
+ if (!utf8)
+ c = *s++;
+ else
+ c = readUTF8char(&s);
+
+ if (c < font->maxascii)
+ g = font->ascii2glyph[c];
+ if (g >= 0) {
+ 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;
+ }
+ }
+
+ PUT8(&t->data[pos], l);
+
+ swf_ResetWriteBits(t);
+ return 0;
+}
+
+int swf_TextCountBits(SWFFONT * font, U8 * s, int scale, U8 * gbits, U8 * abits)
+{
+ return swf_TextCountBits2(font, s, scale, gbits, abits, "iso-8859-1");
+}
+
+int swf_TextSetCharRecord(TAG * t, SWFFONT * font, U8 * s, int scale, U8 gbits, U8 abits)
+{
+ return swf_TextSetCharRecord2(t, font, s, scale, gbits, abits, "iso-8859-1");
+}
+
+int swf_TextCountBitsUTF8(SWFFONT * font, U8 * s, int scale, U8 * gbits, U8 * abits)
+{
+ return swf_TextCountBits2(font, s, scale, gbits, abits, "UTF8");
+}
+
+int swf_TextSetCharRecordUTF8(TAG * t, SWFFONT * font, U8 * s, int scale, U8 gbits, U8 abits)
+{
+ return swf_TextSetCharRecord2(t, font, s, scale, gbits, abits, "UTF8");
+}
+
+U32 swf_TextGetWidth(SWFFONT * font, U8 * s, int scale)
+{
+ U32 res = 0;
+
+ if (font && s) {
+ while (s[0]) {
+ int g = -1;
+ if (*s < font->maxascii)
+ g = font->ascii2glyph[*s];
+ if (g >= 0)
+ res += font->glyph[g].advance / 20;
+ s++;
+ }
+ if (scale)
+ res = (res * scale) / 100;