3 Functions for loading external fonts.
5 Extension module for the rfxswf library.
6 Part of the swftools package.
8 Copyright (c) 2003, 2004 Matthias Kramm
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2 of the License, or
13 (at your option) any later version.
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
26 #include <freetype/freetype.h>
27 #include <freetype/ftglyph.h>
28 #include <freetype/ftsnames.h>
29 #include <freetype/ttnameid.h>
30 #include <freetype/ftoutln.h>
32 static int ft_move_to(FT_Vector* _to, void* user)
34 drawer_t* draw = (drawer_t*)user;
38 draw->moveTo(draw, &to);
41 static int ft_line_to(FT_Vector* _to, void* user)
43 drawer_t* draw = (drawer_t*)user;
47 draw->lineTo(draw, &to);
50 static int ft_cubic_to(FT_Vector* _c1, FT_Vector* _c2, FT_Vector* _to, void* user)
52 drawer_t* draw = (drawer_t*)user;
60 draw_cubicTo(draw, &c1, &c2, &to);
63 static int ft_conic_to(FT_Vector* _c, FT_Vector* _to, void* user)
65 drawer_t* draw = (drawer_t*)user;
71 draw_conicTo(draw, &c, &to);
74 static FT_Outline_Funcs outline_functions =
83 static FT_Library ftlibrary = 0;
85 SWFFONT* swf_LoadTrueTypeFont(char*filename)
96 if(FT_Init_FreeType(&ftlibrary)) {
97 fprintf(stderr, "Couldn't init freetype library!\n");
101 error = FT_New_Face(ftlibrary, filename, 0, &face);
103 fprintf(stderr, "Couldn't load file %s- not a TTF file?\n", filename);
106 if(face->num_glyphs <= 0)
109 font = malloc(sizeof(SWFFONT));
110 memset(font, 0, sizeof(SWFFONT));
113 font->layout = malloc(sizeof(SWFLAYOUT));
114 memset(font->layout, 0, sizeof(SWFLAYOUT));
115 font->layout->bounds = malloc(face->num_glyphs*sizeof(SRECT));
116 font->numchars = face->num_glyphs;
117 font->style = ((face->style_flags&FT_STYLE_FLAG_ITALIC)?FONT_STYLE_ITALIC:0)
118 |((face->style_flags&FT_STYLE_FLAG_BOLD)?FONT_STYLE_BOLD:0);
119 font->encoding = FONT_ENCODING_UNICODE;
120 font->glyph2ascii = malloc(face->num_glyphs*sizeof(U16));
122 memset(font->ascii2glyph, 0, font->maxascii*sizeof(int));
123 font->glyph = malloc(face->num_glyphs*sizeof(SWFGLYPH));
124 memset(font->glyph, 0, face->num_glyphs*sizeof(U16));
125 if(FT_HAS_GLYPH_NAMES(face)) {
126 font->glyphnames = malloc(face->num_glyphs*sizeof(char*));
129 font->layout->ascent = face->ascender; //face->bbox.xMin;
130 font->layout->descent = face->descender; //face->bbox.xMax;
131 font->layout->leading = -face->bbox.xMin;
132 font->layout->kerningcount = 0;
135 font->name = (U8*)strdup(FT_Get_Postscript_Name(face));
137 /* // Map Glyphs to Unicode, version 1 (quick and dirty):
139 for(t=0;t<65536;t++) {
140 int index = FT_Get_Char_Index(face, t);
141 if(index>=0 && index<face->num_glyphs) {
142 if(font->glyph2ascii[index]<0)
143 font->glyph2ascii[index] = t;
147 // Map Glyphs to Unicode, version 2 (much nicer):
148 // (The third way would be the AGL algorithm, as proposed
149 // by Werner Lemberg on freetype@freetype.org)
151 charcode = FT_Get_First_Char(face, &gindex);
154 if(gindex >= 0 && gindex<face->num_glyphs) {
155 if(!font->glyph2ascii[gindex]) {
156 font->glyph2ascii[gindex] = charcode;
157 if(charcode + 1 > font->maxascii) {
158 font->maxascii = charcode + 1;
162 charcode = FT_Get_Next_Char(face, charcode, &gindex);
165 memset(font->glyph2ascii, 0, face->num_glyphs*sizeof(U16));
166 font->ascii2glyph = malloc(font->maxascii*sizeof(int));
168 for(t=0;t<font->maxascii;t++)
169 font->ascii2glyph[t] = FT_Get_Char_Index(face, t);
171 for(t=0; t < face->num_glyphs; t++) {
177 if(FT_HAS_GLYPH_NAMES(face)) {
178 error = FT_Get_Glyph_Name(face, t, name, 127);
180 font->glyphnames[t] = strdup(name);
182 error = FT_Load_Glyph(face, t, FT_LOAD_NO_BITMAP|FT_LOAD_NO_SCALE);
184 error = FT_Get_Glyph(face->glyph, &glyph);
187 FT_Glyph_Get_CBox(glyph, ft_glyph_bbox_unscaled, &bbox);
189 swf_Shape01DrawerInit(&draw, 0);
191 error = FT_Outline_Decompose(&face->glyph->outline, &outline_functions, &draw);
196 font->glyph[t].advance = glyph->advance.x*20/256;
197 font->glyph[t].shape = swf_ShapeDrawerToShape(&draw);
198 //swf_ShapeDrawerGetBBox(&draw);
201 font->layout->bounds[t].xmin = (bbox.xMin*5*20)/266;
202 font->layout->bounds[t].ymin = (bbox.yMin*5*20)/266;
203 font->layout->bounds[t].xmax = (bbox.xMax*5*20)/266;
204 font->layout->bounds[t].ymax = (bbox.yMax*5*20)/266;
206 FT_Done_Glyph(glyph);
210 FT_Done_FreeType(ftlibrary);ftlibrary=0;
216 SWFFONT* swf_LoadTrueTypeFont(char*filename)
218 fprintf(stderr, "Warning: no freetype library- not able to load %s\n", filename);
228 SWFFONT* swf_LoadT1Font(char*filename)
232 float angle,underline;
233 char*fontname,*fullname,*familyname;
240 T1_SetBitmapPad( 16);
241 if ((T1_InitLib(NO_LOGFILE)==NULL)){
242 fprintf(stderr, "Initialization of t1lib failed\n");
245 nr = T1_AddFont(filename);
248 num = T1_SetDefaultEncoding(encoding);
249 for(;num<256;num++) encoding[num] = 0;
251 charnames = T1_GetAllCharNames(nr);
253 angle = T1_GetItalicAngle(nr);
254 fontname = T1_GetFontName(nr);
255 fullname = T1_GetFullName(nr);
256 familyname = T1_GetFamilyName(nr);
257 underline = T1_GetUnderlinePosition(nr);
258 bbox = T1_GetFontBBox(nr);
260 font = (SWFFONT*)malloc(sizeof(SWFFONT));
261 memset(font, 0, sizeof(SWFFONT));
264 font->name = (U8*)strdup(fontname);
265 font->layout = (SWFLAYOUT*)malloc(sizeof(SWFLAYOUT));
266 memset(font->layout, 0, sizeof(SWFLAYOUT));
269 charname = charnames[0];
275 font->maxascii = 256;
276 font->numchars = num;
278 font->style = (/*bold*/0?FONT_STYLE_BOLD:0) + (angle>0.05?FONT_STYLE_ITALIC:0);
280 font->glyph = (SWFGLYPH*)malloc(num*sizeof(SWFGLYPH));
281 memset(font->glyph, 0, num*sizeof(SWFGLYPH));
282 font->glyph2ascii = (U16*)malloc(num*sizeof(U16));
283 memset(font->glyph2ascii, 0, num*sizeof(U16));
284 font->ascii2glyph = (int*)malloc(font->maxascii*sizeof(int));
285 memset(font->ascii2glyph, -1, font->maxascii*sizeof(int));
286 font->layout->ascent = (U16)(underline - bbox.lly);
287 font->layout->descent = (U16)(bbox.ury - underline);
288 font->layout->leading = (U16)(font->layout->ascent -
289 font->layout->descent -
290 (bbox.lly - bbox.ury));
291 font->layout->bounds = (SRECT*)malloc(sizeof(SRECT)*num);
292 memset(font->layout->bounds, 0, sizeof(SRECT)*num);
293 font->layout->kerningcount = 0;
294 font->layout->kerning = 0;
298 charname = charnames[0];
301 T1_OUTLINE * outline = T1_GetCharOutline(nr, c, 100.0, 0);
302 int firstx = outline->dest.x/0xffff;
304 font->ascii2glyph[s] = num;
305 font->glyph2ascii[num] = s;
307 /* fix bounding box */
310 shape2 = swf_ShapeToShape2(font->glyph[s].shape);
311 if(!shape2) { fprintf(stderr, "Shape parse error\n");exit(1);}
312 bbox = swf_GetShapeBoundingBox(shape2);
313 swf_Shape2Free(shape2);
314 font->layout->bounds[num] = bbox;
315 //font->glyph[num].advance = (int)(width/6.4); // 128/20
316 font->glyph[num].advance = bbox.xmax/20;
317 if(!font->glyph[num].advance) {
318 font->glyph[num].advance = firstx;
326 SWFFONT* swf_LoadT1Font(char*filename)
328 fprintf(stderr, "Warning: no t1lib- not able to load %s\n", filename);