73187a3f3b090768e16b8eabf55ce30a3ab74baf
[swftools.git] / pdf2swf / font2swf.cc
1 /* makefonts.cc
2
3    Utility for generating the standard fonts (arial, courier, etc.) in swf-format. 
4    
5    Part of the swftools package.
6
7    Copyright (c) 2001 Matthias Kramm <kramm@quiss.org>
8  
9    This file is distributed under the GPL, see file COPYING for details 
10
11 */
12
13
14 #include <stdio.h>
15 #include <fcntl.h>
16 #include <math.h>
17 #include "../lib/rfxswf.h"
18 #include "swfoutput.h"
19 #include "spline.h"
20
21 #define standardEncodingSize 256
22 #define symbolEncodingSize 256
23 #define zapfDingbatsEncodingSize 256
24 #define macRomanEncodingSize 256
25
26 extern char *standardEncoding[standardEncodingSize];
27 extern char *symbolEncoding[symbolEncodingSize];
28 extern char *zapfDingbatsEncoding[zapfDingbatsEncodingSize];
29 extern char *macRomanEncoding[macRomanEncodingSize];
30
31 extern void drawpath(TAG*tag, T1_OUTLINE*outline, struct swfmatrix*m, int log);
32 extern void resetdrawer();
33 extern void moveto(TAG*tag, plotxy p0);
34 extern void lineto(TAG*tag, plotxy p0);
35
36 SWFFONT * t1font2swffont(int i)
37 {
38     T1_LoadFont(i);
39
40     float angle = T1_GetItalicAngle(i);
41     char*fontname = T1_GetFontName(i);
42     char*fullname = T1_GetFullName(i);
43     char*familyname = T1_GetFamilyName(i);
44     float underline = T1_GetUnderlinePosition(i);
45     BBox bbox = T1_GetFontBBox(i);
46
47     /* if "all" is given, translate the font names in something more
48        readable */
49     if(!strcmp(fullname, "Nimbus Roman No9 L Regular")) fontname = "Helvetica";
50     if(!strcmp(fullname, "Nimbus Roman No9 L Regular Italic")) fontname = "HelveticaItalic";
51     if(!strcmp(fullname, "Nimbus Roman No9 L Medium")) fontname = "HelveticaBold";
52     if(!strcmp(fullname, "Nimbus Roman No9 L Medium Italic")) fontname = "HelveticaBoldItalic";
53     if(!strcmp(fullname, "Nimbus Sans L Regular")) fontname = "Times";
54     if(!strcmp(fullname, "Nimbus Sans L Regular Italic")) fontname = "TimesItalic";
55     if(!strcmp(fullname, "Nimbus Sans L Bold")) fontname = "TimesBold";
56     if(!strcmp(fullname, "Nimbus Sans L Bold Italic")) fontname = "TimesBoldItalic";
57     if(!strcmp(fullname, "Nimbus Mono L Regular")) fontname = "Courier";
58     if(!strcmp(fullname, "Nimbus Mono L Regular Oblique")) fontname = "CourierItalic";
59     if(!strcmp(fullname, "Nimbus Mono L Bold")) fontname = "CourierBold";
60     if(!strcmp(fullname, "Nimbus Mono L Bold Oblique")) fontname = "CourierBoldItalic";
61     if(!strcmp(fullname, "Standard Symbols L")) fontname = "Symbol";
62
63     char ** encoding = standardEncoding;
64     int encodingsize = standardEncodingSize;
65
66     printf("processing \"%s\" (\"%s\")...\n", fullname, fontname);
67
68     if(strstr(fullname, "Dingbats")) {// Zapf Dingbats
69         encoding = zapfDingbatsEncoding;
70         encodingsize = zapfDingbatsEncodingSize;
71     }
72     else if(strstr(fullname, "Symbol")) {// Symbol
73         encoding = symbolEncoding;
74         encodingsize = symbolEncodingSize;
75     }
76
77     SWFFONT * wfont = (SWFFONT*)malloc(sizeof(SWFFONT));
78     SWFFont * font = new SWFFont("", i, "");
79
80     memset(wfont, 0, sizeof(SWFFONT));
81
82     wfont->version = 2;
83     wfont->name = (U8*)strdup(fontname);
84     wfont->layout = (SWFLAYOUT*)malloc(sizeof(SWFLAYOUT));
85     memset(wfont->layout, 0, sizeof(SWFLAYOUT));
86
87     int s,num;
88     num = 0;
89     for(s=0;s<encodingsize;s++)
90     {
91         if(encoding[s]) {
92             T1_OUTLINE*outline = font->getOutline(encoding[s], 0);
93             if(outline) num++;
94         }
95     }
96
97     wfont->maxascii = encodingsize;
98     wfont->numchars = num;
99     
100     wfont->style = (/*bold*/0?FONT_STYLE_BOLD:0) + (angle>0.05?FONT_STYLE_ITALIC:0);
101
102     wfont->glyph = (SWFGLYPH*)malloc(num*sizeof(SWFGLYPH));
103     memset(wfont->glyph, 0, num*sizeof(SWFGLYPH));
104     wfont->glyph2ascii = (U16*)malloc(num*sizeof(U16));
105     memset(wfont->glyph2ascii, 0, num*sizeof(U16));
106     wfont->ascii2glyph = (int*)malloc(encodingsize*sizeof(int));
107     memset(wfont->ascii2glyph, -1, encodingsize*sizeof(int));
108     wfont->layout->ascent = (U16)(underline - bbox.lly);
109     wfont->layout->descent = (U16)(bbox.ury - underline);
110     wfont->layout->leading = (U16)(wfont->layout->ascent - 
111                              wfont->layout->descent -
112                              (bbox.lly - bbox.ury));
113     wfont->layout->bounds = (SRECT*)malloc(sizeof(SRECT)*num);
114     memset(wfont->layout->bounds, 0, sizeof(SRECT)*num);
115     wfont->layout->kerningcount = 0;
116     wfont->layout->kerning = 0;
117   
118     num = 0;
119     for(s=0;s<encodingsize;s++)
120     {
121         if(encoding[s]) {
122             T1_OUTLINE*outline = font->getOutline(encoding[s],0);
123             int width = font->getWidth(encoding[s]);
124
125             if(outline) {
126                 int log = 0;
127                 wfont->ascii2glyph[s] = num;
128                 wfont->glyph2ascii[num] = s;
129                 swf_ShapeNew(&wfont->glyph[num].shape);
130                 SHAPE*shape = wfont->glyph[num].shape;
131                 int firstx = outline->dest.x/0xffff;
132                 
133                 TAG*tag = swf_InsertTag(0,ST_DEFINESHAPE);
134
135                 swfmatrix m;
136                 m.m11 = 1.0;
137                 m.m22 = 1.0;
138                 m.m21 = 0;
139                 m.m12 = 0;
140                 m.m13 = 0;
141                 m.m23 = 0;
142
143                 swf_SetU8(tag,0);
144
145                 shape->bits.fill = 1;
146                 shape->bits.line = 0;
147                 swf_ShapeSetStyle(tag,shape,0,1,0);
148                 resetdrawer();
149
150                 drawpath(tag, outline, &m, log);
151
152                 /*uncomment this to mark the glyph sizes:
153                 plotxy p1,p2; p1.x=0; p1.y=0; p2.x=width/8; p2.y=-width/8;
154                 moveto(tag, p1); lineto(tag, p2); p1.x += 2; p2.x += 2;
155                 lineto(tag, p2); lineto(tag, p1); p1.x -= 2; lineto(tag, p1);// */
156
157                 swf_ShapeSetEnd(tag);
158
159                 wfont->glyph[num].shape->bitlen = (tag->len-1)*8;
160                 wfont->glyph[num].shape->data = (U8*)malloc(tag->len-1);
161                 memcpy(wfont->glyph[num].shape->data, &tag->data[1], tag->len-1);
162                 swf_DeleteTag(tag);
163
164                 /* fix bounding box */
165                 SHAPE2*shape2;
166                 SRECT bbox;
167                 shape2 = swf_ShapeToShape2(shape);
168                 if(!shape2) { fprintf(stderr, "Shape parse error\n");exit(1);}
169                 bbox = swf_GetShapeBoundingBox(shape2->lines);
170                 swf_Shape2Free(shape2);
171                 wfont->layout->bounds[num] = bbox;
172                 //wfont->glyph[num].advance = (int)(width/6.4); // 128/20
173                 wfont->glyph[num].advance = bbox.xmax/20;
174                 if(!wfont->glyph[num].advance) {
175                     wfont->glyph[num].advance = firstx;
176                 }
177                 
178                 num++;
179             }
180         }
181     }
182     return wfont;
183 }
184
185 int main(int argc, char ** argv)
186 {
187   int all=0;
188   if(argc<=1) {
189       printf("Usage: %s font.afm\n", argv[0]);
190       printf("OR:    %s all\n", argv[0]);
191       printf("\n");
192       printf("\tIf \"all\" is given instead of font names, all standard fonts\n");
193       printf("\t(Courier, Arial etc.) will be created\n");
194       return 0;
195   } else {
196       if(!strcmp(argv[1],"all"))
197           all=1;
198   }
199   //TODO: use tempnam here. Check if environment already contains a
200   //T1LIB_CONFIG.
201   putenv( "T1LIB_CONFIG=/tmp/t1lib.config.tmp");
202   FILE*fi = fopen("/tmp/t1lib.config.tmp", "wb");
203   fprintf(fi, "FONTDATABASE=/tmp/FontDataBase\n", SWFTOOLS_DATADIR);
204   fprintf(fi, "ENCODING=%s/fonts:.\n", SWFTOOLS_DATADIR);
205   fprintf(fi, "AFM=%s/fonts:.\n", SWFTOOLS_DATADIR);
206   fprintf(fi, "TYPE1=%s/fonts:.\n", SWFTOOLS_DATADIR);
207   fclose(fi);
208   fi = fopen("/tmp/FontDataBase", "wb");
209   if(all) {
210       fprintf(fi, "14\n");             
211       fprintf(fi, "%s/fonts/n021003l.afm\n", SWFTOOLS_DATADIR);
212       fprintf(fi, "%s/fonts/n021023l.afm\n", SWFTOOLS_DATADIR);
213       fprintf(fi, "%s/fonts/n021004l.afm\n", SWFTOOLS_DATADIR);
214       fprintf(fi, "%s/fonts/n021024l.afm\n", SWFTOOLS_DATADIR);
215       fprintf(fi, "%s/fonts/n019003l.afm\n", SWFTOOLS_DATADIR);
216       fprintf(fi, "%s/fonts/n019023l.afm\n", SWFTOOLS_DATADIR);
217       fprintf(fi, "%s/fonts/n019004l.afm\n", SWFTOOLS_DATADIR);
218       fprintf(fi, "%s/fonts/n019024l.afm\n", SWFTOOLS_DATADIR);
219       fprintf(fi, "%s/fonts/n022003l.afm\n", SWFTOOLS_DATADIR);
220       fprintf(fi, "%s/fonts/n022023l.afm\n", SWFTOOLS_DATADIR);
221       fprintf(fi, "%s/fonts/n022004l.afm\n", SWFTOOLS_DATADIR);
222       fprintf(fi, "%s/fonts/n022024l.afm\n", SWFTOOLS_DATADIR);
223       fprintf(fi, "%s/fonts/s050000l.afm\n", SWFTOOLS_DATADIR);
224       fprintf(fi, "%s/fonts/d050000l.afm\n", SWFTOOLS_DATADIR);
225   } else {
226     fprintf(fi, "%d\n",argc-1);
227     int t;
228     for(t=1;t<argc;t++) {
229         fprintf(fi, "%s\n",argv[t]);
230     }
231   }
232   fclose(fi);
233   /* initialize t1lib */
234   T1_SetBitmapPad( 16);
235   if ((T1_InitLib(NO_LOGFILE)==NULL)){
236       fprintf(stderr, "Initialization of t1lib failed\n");
237       exit(1);
238   }
239   unlink("/tmp/t1lib.config.tmp");
240
241   int i,num;
242   for( i=0; i<T1_Get_no_fonts(); i++)
243   {
244     SWFFONT * font = t1font2swffont(i);
245     
246     char filename[128];
247     sprintf(filename, "%s.swf", font->name);
248     swf_WriteFont(font, filename);
249     swf_FontFree(font);
250   }
251   unlink("/tmp/FontDataBase");
252 }
253
254