From 5d8d800fc5ba13dadea83dd0ca63bfe1211d9372 Mon Sep 17 00:00:00 2001 From: kramm Date: Sat, 31 Jan 2004 20:01:57 +0000 Subject: [PATCH] removed MAX_CHAR_PER_FONT, made TTF support work. --- lib/modules/swffont.c | 80 ++++++++++++++++++++--------- lib/modules/swftext.c | 134 +++++++++++++++++++++++++++++++++++-------------- lib/rfxswf.h | 5 +- 3 files changed, 155 insertions(+), 64 deletions(-) diff --git a/lib/modules/swffont.c b/lib/modules/swffont.c index d6f157b..db4eab7 100644 --- a/lib/modules/swffont.c +++ b/lib/modules/swffont.c @@ -29,12 +29,15 @@ #include #include +#define FT_SCALE 1 +#define FT_SUBPIXELS 64 + static int ft_move_to(FT_Vector* _to, void* user) { drawer_t* draw = (drawer_t*)user; FPOINT to; - to.x = _to->x/256.0; - to.y = _to->y/256.0; + to.x = _to->x*FT_SCALE/(float)FT_SUBPIXELS; + to.y = -_to->y*FT_SCALE/(float)FT_SUBPIXELS; draw->moveTo(draw, &to); return 0; } @@ -42,8 +45,8 @@ static int ft_line_to(FT_Vector* _to, void* user) { drawer_t* draw = (drawer_t*)user; FPOINT to; - to.x = _to->x/256.0; - to.y = _to->y/256.0; + to.x = _to->x*FT_SCALE/(float)FT_SUBPIXELS; + to.y = -_to->y*FT_SCALE/(float)FT_SUBPIXELS; draw->lineTo(draw, &to); return 0; } @@ -51,12 +54,12 @@ static int ft_cubic_to(FT_Vector* _c1, FT_Vector* _c2, FT_Vector* _to, void* use { drawer_t* draw = (drawer_t*)user; FPOINT c1,c2,to; - to.x = _to->x/256.0; - to.y = _to->y/256.0; - c1.x = _c1->x/256.0; - c1.y = _c1->y/256.0; - c2.x = _c2->x/256.0; - c2.y = _c2->y/256.0; + to.x = _to->x*FT_SCALE/(float)FT_SUBPIXELS; + to.y = -_to->y*FT_SCALE/(float)FT_SUBPIXELS; + c1.x = _c1->x*FT_SCALE/(float)FT_SUBPIXELS; + c1.y = -_c1->y*FT_SCALE/(float)FT_SUBPIXELS; + c2.x = _c2->x*FT_SCALE/(float)FT_SUBPIXELS; + c2.y = -_c2->y*FT_SCALE/(float)FT_SUBPIXELS; draw_cubicTo(draw, &c1, &c2, &to); return 0; } @@ -64,10 +67,10 @@ static int ft_conic_to(FT_Vector* _c, FT_Vector* _to, void* user) { drawer_t* draw = (drawer_t*)user; FPOINT c,to; - to.x = _to->x/256.0; - to.y = _to->y/256.0; - c.x = _c->x/256.0; - c.y = _c->y/256.0; + to.x = _to->x*FT_SCALE/(float)FT_SUBPIXELS; + to.y = -_to->y*FT_SCALE/(float)FT_SUBPIXELS; + c.x = _c->x*FT_SCALE/(float)FT_SUBPIXELS; + c.y = -_c->y*FT_SCALE/(float)FT_SUBPIXELS; draw_conicTo(draw, &c, &to); return 0; } @@ -118,8 +121,9 @@ SWFFONT* swf_LoadTrueTypeFont(char*filename) |((face->style_flags&FT_STYLE_FLAG_BOLD)?FONT_STYLE_BOLD:0); font->encoding = FONT_ENCODING_UNICODE; font->glyph2ascii = malloc(face->num_glyphs*sizeof(U16)); + memset(font->glyph2ascii, 0, face->num_glyphs*sizeof(U16)); font->maxascii = 0; - memset(font->ascii2glyph, 0, font->maxascii*sizeof(int)); + memset(font->ascii2glyph, -1, font->maxascii*sizeof(int)); font->glyph = malloc(face->num_glyphs*sizeof(SWFGLYPH)); memset(font->glyph, 0, face->num_glyphs*sizeof(U16)); if(FT_HAS_GLYPH_NAMES(face)) { @@ -162,17 +166,21 @@ SWFFONT* swf_LoadTrueTypeFont(char*filename) charcode = FT_Get_Next_Char(face, charcode, &gindex); } - memset(font->glyph2ascii, 0, face->num_glyphs*sizeof(U16)); font->ascii2glyph = malloc(font->maxascii*sizeof(int)); - for(t=0;tmaxascii;t++) + for(t=0;tmaxascii;t++) { font->ascii2glyph[t] = FT_Get_Char_Index(face, t); + if(!font->ascii2glyph[t]) + font->ascii2glyph[t] = -1; + } for(t=0; t < face->num_glyphs; t++) { FT_Glyph glyph; FT_BBox bbox; + FT_Matrix matrix; char name[128]; drawer_t draw; + int ret; name[0]=0; if(FT_HAS_GLYPH_NAMES(face)) { error = FT_Get_Glyph_Name(face, t, name, 127); @@ -185,23 +193,47 @@ SWFFONT* swf_LoadTrueTypeFont(char*filename) if(error) return 0; FT_Glyph_Get_CBox(glyph, ft_glyph_bbox_unscaled, &bbox); + bbox.yMin = -bbox.yMin; + bbox.yMax = -bbox.yMax; + if(bbox.xMax < bbox.xMin) { + // swap + bbox.xMax ^= bbox.xMin; + bbox.xMin ^= bbox.xMax; + bbox.xMax ^= bbox.xMin; + } + if(bbox.yMax < bbox.yMin) { + // swap + bbox.yMax ^= bbox.yMin; + bbox.yMin ^= bbox.yMax; + bbox.yMax ^= bbox.yMin; + } swf_Shape01DrawerInit(&draw, 0); + //error = FT_Outline_Decompose(&face->glyph->outline, &outline_functions, &draw); error = FT_Outline_Decompose(&face->glyph->outline, &outline_functions, &draw); if(error) return 0; draw.finish(&draw); - font->glyph[t].advance = glyph->advance.x*20/256; +#if 0 + if(bbox.xMin > 0) { + font->glyph[t].advance = (bbox.xMax*FT_SCALE)/FT_SUBPIXELS; + } else { + font->glyph[t].advance = ((bbox.xMax - bbox.xMin)*FT_SCALE)/FT_SUBPIXELS; + } +#else + font->glyph[t].advance = glyph->advance.x/65536; +#endif + font->glyph[t].shape = swf_ShapeDrawerToShape(&draw); - //swf_ShapeDrawerGetBBox(&draw); + + font->layout->bounds[t].xmin = (bbox.xMin*FT_SCALE*20)/FT_SUBPIXELS; + font->layout->bounds[t].ymin = (bbox.yMin*FT_SCALE*20)/FT_SUBPIXELS; + font->layout->bounds[t].xmax = (bbox.xMax*FT_SCALE*20)/FT_SUBPIXELS; + font->layout->bounds[t].ymax = (bbox.yMax*FT_SCALE*20)/FT_SUBPIXELS; + draw.dealloc(&draw); - - font->layout->bounds[t].xmin = (bbox.xMin*5*20)/266; - font->layout->bounds[t].ymin = (bbox.yMin*5*20)/266; - font->layout->bounds[t].xmax = (bbox.xMax*5*20)/266; - font->layout->bounds[t].ymax = (bbox.yMax*5*20)/266; FT_Done_Glyph(glyph); } diff --git a/lib/modules/swftext.c b/lib/modules/swftext.c index 433dc81..cb55d76 100644 --- a/lib/modules/swftext.c +++ b/lib/modules/swftext.c @@ -319,7 +319,11 @@ int swf_FontExtract_DefineTextCallback(int id,SWFFONT * f,TAG * t,int jobs, flags = swf_GetU8(t); while(flags) - { if (flags&TF_TEXTCONTROL) + { + // FIXME: according to open-swf@macromedia.com, this is wrong. + // it should alternate textcontrol and text arrays, not + // rely on the high bit. (and length can be 0-255). + if (flags&TF_TEXTCONTROL) { if (flags&TF_HASFONT) fid = swf_GetU16(t); if (flags&TF_HASCOLOR) { swf_GetU8(t); // rgb @@ -417,7 +421,7 @@ int swf_FontReduce(SWFFONT * f,FONTUSAGE * use) j = 0; for (i=0;inumchars;i++) if (f->glyph[i].shape) - { if (f->glyph2ascii[i]glyph2ascii[i]numchars&& use->code[f->glyph2ascii[i]]) { f->ascii2glyph[f->glyph2ascii[i]] = j; f->glyph2ascii[j] = f->glyph2ascii[i]; @@ -438,12 +442,18 @@ int swf_FontReduce(SWFFONT * f,FONTUSAGE * use) return j; } -int swf_FontInitUsage(FONTUSAGE * use) +int swf_FontInitUsage(SWFFONT* f, FONTUSAGE * use) { if (!use) return -1; - memset(use->code,0,sizeof(use->code[0])*MAX_CHAR_PER_FONT); + use->code = malloc(sizeof(use->code[0])*f->numchars); + memset(use->code,0,sizeof(use->code[0])*f->numchars); return 0; } +void swf_FontClearUsage(SWFFONT* f, FONTUSAGE * use) +{ if (!use) return; + free(use->code); +} + int swf_FontUse(FONTUSAGE * use,U8 * s) { if ((!use)||(!s)) return -1; while (s[0]) @@ -483,6 +493,17 @@ int swf_FontSetDefine(TAG * t,SWFFONT * f) return 0; } +static inline int fontSize(SWFFONT*font) +{ + int t; + int size = 0; + for(t=0;tnumchars;t++) { + int l = (font->glyph[t].shape->bitlen+7)/8; + size += l+1; + } + return size + (font->numchars+1)*2; +} + int swf_FontSetDefine2(TAG *tag, SWFFONT * f) { U8 flags = 0; @@ -490,6 +511,7 @@ int swf_FontSetDefine2(TAG *tag, SWFFONT * f) int pos; int pos2; swf_SetU16(tag, f->id); + if(f->layout) flags |= 128; // haslayout if(f->numchars>256) @@ -498,7 +520,12 @@ int swf_FontSetDefine2(TAG *tag, SWFFONT * f) flags |= 1; // bold if(f->style & FONT_STYLE_ITALIC) flags |= 2; // italic - /* wideoffs 8 */ + if(f->maxascii>=256) + flags |= 4; //wide codecs + if(fontSize(f)>65535) + flags |= 8; //wide offsets + flags |= 8; //FIXME: the above check doesn't work + if(f->encoding & FONT_ENCODING_ANSI) flags |= 16; // ansi if(f->encoding & FONT_ENCODING_UNICODE) @@ -520,25 +547,38 @@ int swf_FontSetDefine2(TAG *tag, SWFFONT * f) swf_SetU16(tag, f->numchars); /* font offset table */ pos = tag->len; - for(t=0;tnumchars;t++) + for(t=0;t<=f->numchars;t++) { - swf_SetU16(tag, /* fontoffset */ 0); /*placeholder*/ + if(flags&8) + swf_SetU32(tag, /* fontoffset */ 0); /*placeholder*/ + else + swf_SetU16(tag, /* fontoffset */ 0); /*placeholder*/ } - pos2 = tag->len; - swf_SetU16(tag, 0); //fontcode-fontoffset - for(t=0;tnumchars;t++) { - tag->data[pos + t*2] = (tag->len-pos); - tag->data[pos + t*2 + 1] = (tag->len-pos) >> 8; - swf_SetSimpleShape(tag, f->glyph[t].shape); + + for(t=0;t<=f->numchars;t++) { + if(flags&8) { + tag->data[pos + t*4 ] = (tag->len-pos); + tag->data[pos + t*4 + 1] = (tag->len-pos) >> 8; + tag->data[pos + t*4 + 2] = (tag->len-pos) >> 16; + tag->data[pos + t*4 + 3] = (tag->len-pos) >> 24; + } else { + if(tag->len - pos > 65535) { + fprintf(stderr, "Internal error: Font too big and WideOffsets flag not set\n"); + exit(1); + } + tag->data[pos + t*2 ] = (tag->len-pos); + tag->data[pos + t*2 + 1] = (tag->len-pos) >> 8; + } + if(tnumchars) + swf_SetSimpleShape(tag, f->glyph[t].shape); } - tag->data[pos2] = tag->len - pos; - tag->data[pos2 + 1] = (tag->len - pos) >> 8; /* font code table */ if(flags & 4) /* wide codes */ { - for(t=0;tnumchars;t++) + for(t=0;tnumchars;t++) { swf_SetU16(tag,f->glyph2ascii[t]); + } } else { for(t=0;tnumchars;t++) swf_SetU8(tag,f->glyph2ascii[t]); @@ -557,11 +597,11 @@ int swf_FontSetDefine2(TAG *tag, SWFFONT * f) swf_SetU16(tag, f->layout->kerningcount); for(t=0;tlayout->kerningcount;t++) { if(flags & 4) /* wide codes */ { - swf_SetU8(tag,f->layout->kerning[t].char1); - swf_SetU8(tag,f->layout->kerning[t].char2); - } else { 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); } @@ -661,6 +701,13 @@ void swf_FontFree(SWFFONT * f) free(f->glyph2ascii); f->glyph2ascii = NULL; } + if(f->glyphnames) { + int t; + for(t=0;tnumchars;t++) { + free(f->glyphnames[t]); + } + free(f->glyphnames); + } } free(f); } @@ -804,8 +851,8 @@ void swf_WriteFont(SWFFONT*font, char* filename) did use definefont2 -mk*/ t = swf_InsertTag(NULL,ST_SETBACKGROUNDCOLOR); swf.firstTag = t; - rgb.r = 0xff; - rgb.g = 0xff; + rgb.r = 0xef; + rgb.g = 0xef; rgb.b = 0xff; swf_SetRGB(t,&rgb); if(!useDefineFont2) { @@ -818,24 +865,35 @@ void swf_WriteFont(SWFFONT*font, char* filename) swf_FontSetDefine2(t,font); } - if(1) //useDefineFont2 - { int textscale = 400; + if(1) //neccessary only for df1, but pretty to look at anyhow, so do it always + { + int textscale = 400; int s; int xmax = 0; - int ymax = textscale * 2 * (font->maxascii/16+1); + int ymax = 0; + int ypos = 1; U8 gbits,abits; - U8 text[MAX_CHAR_PER_FONT+1]; - int x,y; - text[MAX_CHAR_PER_FONT]=0; + int x,y,c; + + c=0; for(s=0;smaxascii;s++) { int g = font->ascii2glyph[s]; - text[s] = s; if(g>=0) { - if(font->glyph[g].advance*textscale/64 > xmax) + if(font->glyph[g].advance*textscale/64 > xmax) { xmax = font->glyph[g].advance*textscale/64; + } + c++; + } + if((s&15)==0) { + if(c) { + ypos++; + } + c=0; } } + ymax = ypos*textscale*2; + swf.movieSize.xmax = xmax*20; swf.movieSize.ymax = ymax; @@ -845,7 +903,7 @@ void swf_WriteFont(SWFFONT*font, char* filename) r.xmin = 0; r.ymin = 0; - r.xmax = swf.movieSize.xmax*20; + r.xmax = swf.movieSize.xmax; r.ymax = swf.movieSize.ymax; swf_SetRect(t,&r); @@ -861,10 +919,10 @@ void swf_WriteFont(SWFFONT*font, char* filename) rgb.r = 0x00; rgb.g = 0x00; rgb.b = 0x00; - for(y=0;y<=((font->maxascii-1)/16);y++) + ypos = 1; + for(y=0;y<((font->maxascii+15)/16);y++) { int c=0,lastx=-1; - /* TODO: firstx?? */ for(x=0;x<16;x++) { int g = (y*16+xmaxascii)?font->ascii2glyph[y*16+x]:-1; if(g>=0 && font->glyph[g].shape) { @@ -874,7 +932,7 @@ void swf_WriteFont(SWFFONT*font, char* filename) } } if(c) { - swf_TextSetInfoRecord(t,font,textscale,&rgb,lastx+1,textscale*y*2); + swf_TextSetInfoRecord(t,font,textscale,&rgb,lastx+1,textscale*ypos*2); for(x=0;x<16;x++) { int g = (y*16+xmaxascii)?font->ascii2glyph[y*16+x]:-1; @@ -889,6 +947,7 @@ void swf_WriteFont(SWFFONT*font, char* filename) swf_ResetWriteBits(t); } } + ypos++; } } swf_SetU8(t,0); @@ -899,6 +958,7 @@ void swf_WriteFont(SWFFONT*font, char* filename) swf_ObjectPlace(t,font->id+1,1,NULL,NULL,NULL); t = swf_InsertTag(t,ST_SHOWFRAME); + } t = swf_InsertTag(t,ST_END); @@ -1092,7 +1152,7 @@ static U32 readUTF8char(char**text) return *((*text)++); } -void swf_DrawText(SWFSHAPEDRAWER*draw, SWFFONT*font, char*text) +void swf_DrawText(drawer_t*draw, SWFFONT*font, char*text) { char*s = text; int advance = 0; @@ -1109,19 +1169,19 @@ void swf_DrawText(SWFSHAPEDRAWER*draw, SWFFONT*font, char*text) FPOINT to; to.x = l->x/20.0+advance; to.y = l->y/20.0; - swf_DrawerMoveTo(draw, &to); + draw->moveTo(draw, &to); } else if(l->type == lineTo) { FPOINT to; to.x = l->x/20.0+advance; to.y = l->y/20.0; - swf_DrawerLineTo(draw, &to); + draw->lineTo(draw, &to); } else if(l->type == splineTo) { FPOINT mid,to; mid.x = l->sx/20.0+advance; mid.y = l->sy/20.0; to.x = l->x/20.0+advance; to.y = l->y/20.0; - swf_DrawerSplineTo(draw, &mid, &to); + draw->splineTo(draw, &mid, &to); } l = l->next; } diff --git a/lib/rfxswf.h b/lib/rfxswf.h index 55ddf2e..ea60818 100644 --- a/lib/rfxswf.h +++ b/lib/rfxswf.h @@ -502,10 +502,9 @@ typedef struct _SWFFONT char ** glyphnames; } SWFFONT, * LPSWFFONT; -#define MAX_CHAR_PER_FONT 512 // does not support wide characters ! typedef struct _FONTUSAGE -{ U8 code[MAX_CHAR_PER_FONT]; +{ U8* code; } FONTUSAGE, * LPFONTUSAGE; #define ET_HASTEXT 32768 @@ -547,7 +546,7 @@ int swf_FontIsBold(SWFFONT * f); int swf_FontSetID(SWFFONT * f,U16 id); int swf_FontReduce(SWFFONT * f,FONTUSAGE * use); -int swf_FontInitUsage(FONTUSAGE * use); +int swf_FontInitUsage(SWFFONT * f,FONTUSAGE * use); int swf_FontUse(FONTUSAGE * use,U8 * s); int swf_FontSetDefine(TAG * t,SWFFONT * f); -- 1.7.10.4