4 * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version. The Blender
10 * Foundation also sells licenses for use in proprietary software under
11 * the Blender License. See http://www.blender.org/BL/ for information
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software Foundation,
21 * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
24 * All rights reserved.
26 * The Original Code is: all of this file.
28 * Contributor(s): none yet.
30 * ***** END GPL/BL DUAL LICENSE BLOCK *****
31 * fromtype1 - Convert an Adobe type 1 font into .of or .sf format.
32 * Paul Haeberli - 1990
41 #include "MEM_guardedalloc.h"
43 #include "BLI_vfontdata.h"
44 #include "BLI_blenlib.h"
46 #include "DNA_packedFile_types.h"
47 #include "DNA_curve_types.h"
55 typedef struct chardesc {
56 short movex, movey; /* advance */
57 short llx, lly; /* bounding box */
59 short *data; /* char data */
63 typedef struct objfnt {
64 struct objfnt *freeaddr; /* if freeaddr != 0, objfnt is one chunck */
66 short charmin, charmax;
72 #define OFMAGIC 0x93339333
78 /* ops for tmesh characters */
80 #define TM_BGNTMESH (1)
81 #define TM_SWAPTMESH (2)
82 #define TM_ENDBGNTMESH (3)
83 #define TM_RETENDTMESH (4)
86 /* ops for poly characters */
88 #define PO_BGNLOOP (1)
89 #define PO_ENDBGNLOOP (2)
90 #define PO_RETENDLOOP (3)
93 /* ops for spline characters */
97 #define SP_CURVETO (3)
98 #define SP_CLOSEPATH (4)
99 #define SP_RETCLOSEPATH (5)
103 #define MIN_ASCII ' '
104 #define MAX_ASCII '~'
105 #define NASCII (256 - 32)
107 #define NOBBOX (30000)
109 typedef struct pschar {
122 #define MAXSUBRS 1000
123 #define MAXCHARS 1000
126 /* some local thingies */
127 static void rcurveto( int dx1, int dy1, int dx2, int dy2, int dx3, int dy3);
128 static void makeobjfont(int savesplines);
129 static void drawchar(int c);
130 static void runprog(void);
131 static int chartoindex(objfnt *fnt, int c);
132 static short STDtoISO(short c);
133 static char * newfgets(char * s, int n, PackedFile * pf);
134 static int readfontmatrix(PackedFile * pf, float mat[2][2]);
135 static char mdecrypt(char cipher);
136 static void decryptall(void);
137 static int decodetype1(PackedFile * pf, char *outname);
138 static void fakefopen(void);
139 static char *fakefread(int n);
140 static void setcharlist(void);
141 static void initpcstack(void);
142 static char *poppc(void);
143 static void initstack(void);
144 static void push(int val);
145 static int pop(void);
146 static void initretstack(void);
147 static void retpush(int val);
148 static int retpop(void);
149 static void subr1(void);
150 static void subr2(void);
151 static void subr0(void);
152 static void append_poly_offset(short ofsx, short ofsy, short * data);
153 static void append_spline_offset(short ofsx, short ofsy, short * data);
154 static void setwidth(int w, int x);
155 static void poly_beginchar(void);
156 static void poly_endchar(void);
157 static void poly_close(void);
158 static void poly_pnt(float x, float y);
159 static void spline_beginchar(void);
160 static void spline_endchar(void);
161 static void spline_close(void);
162 static void spline_line(float x0, float y0, float x1, float y1);
163 static void spline_curveto(float x0, float y0, float x1, float y1, float x2, float y2, float x3, float y3);
164 static void savestart(int x, int y);
165 static void sbpoint( int x, int y);
166 static void rmoveto( int x, int y);
167 static void drawline(float x0, float y0, float x1, float y1, float dx0, float dy0, float dx1, float dy1);
168 static void rlineto( int x, int y);
169 static void closepath(void);
170 static void bezadapt( float x0, float y0, float x1, float y1, float x2, float y2, float x3, float y3, float beztol);
171 static void drawbez( float x0, float y0, float x1, float y1, float x2, float y2, float x3, float y3);
172 static int docommand(int cmd);
174 /* some local vars */
175 static int startx, starty;
176 static int curx, cury;
177 static int nextx, nexty;
178 static int delx, dely;
182 /* postscript commands */
189 #define RRCURVETO (8)
190 #define CLOSEPATH (9)
191 #define CALLSUBR (10)
197 #define VHCURVETO (30)
198 #define HVCURVETO (31)
199 #define DOTSECTION (256+0)
200 #define VSTEM3 (256+1)
201 #define HSTEM3 (256+2)
205 #define CALLOTHERSUBR (256+16)
207 #define SETCURRENTPOINT (256+33)
210 /* some dirt for windows */
212 #include "BLI_winstuff.h"
215 static char oneline[LINELEN];
218 static unsigned short int mr;
223 static short chardata[2000];
226 static int thecharwidth, thesidebearing;
227 static int npnts, nloops;
233 static float beztol = 100.0;
235 /* extern: from libfm */
237 static char *my_subrs[MAXSUBRS];
238 static unsigned int my_sublen[MAXSUBRS];
239 static char *my_chars[MAXCHARS];
240 static unsigned int my_charlen[MAXCHARS];
241 static char *my_charname[MAXCHARS];
242 static int my_nsubrs, my_nchars;
244 static short sidebearing[MAXCHARS];
245 static char tok[LINELEN];
246 static int sp_npnts, sp_nloops;
249 * interpreter globals
253 static float mat[2][2];
254 static char *pcstack[100];
258 static int coordsave[7][2];
260 static int retstack[1000];
262 static int stack[1000];
264 static int savesplines = 1;
266 static pschar ISOcharlist[NASCII] = {
270 "/numbersign", 043, 0,
273 "/ampersand", 046, 0,
274 "/quoteright", 047, 0,
276 "/parenleft", 050, 0,
277 "/parenright", 051, 0,
297 "/semicolon", 073, 0,
333 "/bracketleft", 0133, 0,
334 "/backslash", 0134, 0,
335 "/bracketright", 0135, 0,
336 "/asciicircum", 0136, 0,
337 "/underscore", 0137, 0,
339 "/quoteleft", 0140, 0,
369 "/braceleft", 0173, 0,
371 "/braceright", 0175, 0,
372 "/asciitilde", 0176, 0,
376 /* nonstandard defs */
378 "/quotedblleft", 0200, 0,
379 "/quotedblright", 0201, 0,
380 "/quotedblbase", 0202, 0,
381 "/quotesinglbase", 0203, 0,
382 "/guilsinglleft", 0204, 0,
383 "/guilsinglright", 0205, 0,
387 "/daggerdbl", 0210, 0,
388 "/trademark", 0211, 0,
390 "/perthousand", 0213, 0,
396 /* endnonstandard defs */
398 "/dotlessi", 0220, 0,
401 "/circumflex", 0223, 0,
405 "/dotaccent", 0227, 0,
412 "/hungarumlaut", 0235, 0,
417 "/exclamdown", 0241, 0,
419 "/sterling", 0243, 0,
422 "/brokenbar", 0246, 0,
425 "/dieresis", 0250, 0,
426 "/copyright", 0251, 0,
427 "/ordfeminine", 0252, 0,
428 "/guillemotleft", 0253, 0,
429 "/logicalnot", 0254, 0,
431 "/registered", 0256, 0,
435 "/plusminus", 0261, 0,
436 "/twosuperior", 0262, 0,
437 "/threesuperior", 0263, 0,
440 "/paragraph", 0266, 0,
441 "/periodcentered", 0267, 0,
444 "/onesuperior", 0271, 0,
445 "/ordmasculine", 0272, 0,
446 "/guillemotright", 0273, 0,
447 "/onequarter", 0274, 0,
449 "/threequarters", 0276, 0,
450 "/questiondown", 0277, 0,
454 "/Acircumflex", 0302, 0,
456 "/Adieresis", 0304, 0,
459 "/Ccedilla", 0307, 0,
463 "/Ecircumflex", 0312, 0,
464 "/Edieresis", 0313, 0,
467 "/Icircumflex", 0316, 0,
468 "/Idieresis", 0317, 0,
474 "/Ocircumflex", 0324, 0,
476 "/Odieresis", 0326, 0,
477 "/multiply", 0327, 0,
482 "/Ucircumflex", 0333, 0,
483 "/Udieresis", 0334, 0,
486 "/germandbls", 0337, 0,
490 "/acircumflex", 0342, 0,
492 "/adieresis", 0344, 0,
495 "/ccedilla", 0347, 0,
499 "/ecircumflex", 0352, 0,
500 "/edieresis", 0353, 0,
503 "/icircumflex", 0356, 0,
504 "/idieresis", 0357, 0,
510 "/ocircumflex", 0364, 0,
512 "/odieresis", 0366, 0,
518 "/ucircumflex", 0373, 0,
519 "/udieresis", 0374, 0,
522 "/ydieresis", 0377, 0,
526 static short STDvsISO [][2] = {
528 0351, 0330, /* Oslash */
529 0302, 0222, /* acute */
531 0306, 0226, /* breve */
532 0317, 0237, /* caron */
533 0313, 0270, /* cedilla */
534 0303, 0223, /* circumflex */
535 0250, 0244, /* currency */
536 0310, 0250, /* dieresis */
537 0307, 0227, /* dotaccent */
538 0365, 0220, /* dotlessi */
539 0373, 0337, /* germandbls */
540 0301, 0221, /* grave */
541 0315, 0235, /* hungarumlaut */
542 0055, 0255, /* hyphen */
543 0305, 0257, /* macron */
544 0316, 0236, /* ogenek */
545 0343, 0252, /* ordfeminine */
546 0353, 0272, /* ordmasculine */
547 0371, 0370, /* oslash */
548 0264, 0267, /* periodcentered */
549 0312, 0232, /* ring */
550 0304, 0224, /* tilde */
553 /* from objfont.c, rest is in lfm_s !!*/
557 static int chartoindex(objfnt *fnt, int c)
563 return c-fnt->charmin;
567 static chardesc *getchardesc(objfnt *fnt, int c)
571 index = chartoindex(fnt,c);
574 return fnt->my_chars+index;
577 static objfnt *newobjfnt(int type, int charmin, int charmax, int fscale)
581 fnt = (objfnt *)MEM_mallocN(sizeof(objfnt), "newobjfnt");
584 fnt->charmin = charmin;
585 fnt->charmax = charmax;
586 fnt->my_nchars = fnt->charmax-fnt->charmin+1;
588 fnt->my_chars = (chardesc *)MEM_mallocN(fnt->my_nchars*sizeof(chardesc), "newobjfnt2");
589 memset(fnt->my_chars, 0, fnt->my_nchars*sizeof(chardesc));
594 static void addchardata (objfnt * fnt, int c, short * data, int nshorts)
599 index = chartoindex(fnt,c);
601 fprintf(stderr,"Addchardata bad poop\n");
604 cd = fnt->my_chars+index;
606 cd->datalen = nshorts*sizeof(short);
607 cd->data = (short *)MEM_mallocN(cd->datalen, "addchardata");
608 memcpy(cd->data, data, cd->datalen);
611 static void addcharmetrics(objfnt *fnt, int c, int movex, int movey)
616 index = chartoindex(fnt,c);
618 fprintf(stderr,"Addcharmetrics bad poop\n");
621 cd = fnt->my_chars+index;
627 static void fakechar(objfnt *fnt, int c, int width)
631 chardata[0] = PO_RET;
632 addchardata(fnt,c,chardata,1);
633 addcharmetrics(fnt,c,width,0);
637 static void freeobjfnt(objfnt * fnt)
643 for(i=0; i<fnt->my_nchars; i++) {
648 MEM_freeN(fnt->my_chars);
655 static short STDtoISO(short c)
657 short i = (sizeof(STDvsISO) / (2 * sizeof(short))) - 1;
660 if (STDvsISO[i][0] == c) return (STDvsISO[i][1]);
667 * read the font matrix out of the font file
671 static char * newfgets(char * s, int n, PackedFile * pf){
678 c = ((char *) pf->data)[pf->seek];
680 if (pf->seek > pf->size){
681 if (read == 0) return (0);
685 if (c == 10 || c == 13){
696 static int readfontmatrix(PackedFile * pf, float mat[2][2])
699 float a, b, c, d, e, f;
703 /* look for the FontMatrix def */
705 if(!newfgets(oneline, LINELEN, pf)) {
706 fprintf(stderr,"fromtype1: no FontMatrix found\n");
709 cptr = strchr(oneline,'/');
711 if(strncmp(cptr,"/FontMatrix",11) == 0) {
712 cptr = strchr(cptr,'[');
714 fprintf(stderr,"fromtype1: bad FontMatrix line\n");
717 sscanf(cptr+1,"%f %f %f %f %f %f\n",&a,&b,&c,&d,&e,&f);
723 mat[0][0] = 1000.0*a;
724 mat[1][0] = 1000.0*b;
725 mat[0][1] = 1000.0*c;
726 mat[1][1] = 1000.0*d;
736 static void resetdecrypt(int n)
744 * decryption subroutines
748 static char mdecrypt(char cipher)
752 plain = (cipher^(mr>>8));
753 mr = (cipher+mr)*MC1 + MC2;
757 static void decryptdata(char * cptr, int n)
760 *cptr = mdecrypt(*cptr);
765 static int decryptprogram(char *buf, int len)
770 for(i=0; i<len; i++) {
774 buf[i-SKIP] = mdecrypt(buf[i]);
779 static void decryptall(void)
783 for(i=0; i<my_nsubrs; i++)
784 my_sublen[i] = decryptprogram(my_subrs[i],my_sublen[i]);
785 for(i=0; i<my_nchars; i++)
786 my_charlen[i] = decryptprogram(my_chars[i],my_charlen[i]);
791 * decode the eexec part of the file
795 static int decodetype1(PackedFile * pf, char *outname)
798 int i, totlen, hexbytes, c;
804 for(i=0; i<256; i++) {
807 else if(i>='a' && i<='f')
808 hextab[i] = 10+i-'a';
809 else if(i>='A' && i<='F')
810 hextab[i] = 10+i-'A';
818 /* allocate buffers */
820 hexdat = (char *)MEM_mallocN(totlen, "hexdat");
821 bindat = (char *)MEM_mallocN(totlen, "bindat");
823 /* look for eexec part of file */
825 if(!newfgets(oneline, LINELEN, pf)) {
826 fprintf(stderr,"fromtype1: no currentfile eexec found\n");
830 if(strcmp(oneline,"currentfile eexe") == 0)
834 /* initialize decryption variables */
837 /* first byte == 0 for binary data (???) */
839 c = ((char *) pf->data)[pf->seek];
841 if (hextab[c] != NOTHEX){
842 /* read all the hex bytes into the hex buffer */
844 while(newfgets(oneline, LINELEN, pf)) {
845 hptr = (char *)oneline;
847 if(hextab[*hptr] != NOTHEX)
848 hexdat[hexbytes++] = *hptr;
853 /* check number of hex bytes */
856 datbytes = hexbytes/2;
858 /* translate hex data to binary */
863 *bptr++ = (hextab[hptr[0]]<<4)+hextab[hptr[1]];
867 /* decrypt the data */
868 decryptdata(bindat,datbytes);
871 datbytes = pf->size - pf->seek;
872 memcpy(bindat, ((char *) pf->data) + pf->seek, datbytes);
874 if ((bindat[2] << 8 + bindat[3]) == 0x800){
875 /* order data (remove 6 bytes headers) */
877 hptr = bptr = bindat + 4;
881 if (i > 2046) c = 2046;
884 memcpy(bptr, hptr, c);
891 /* decrypt the data */
892 decryptdata(bindat+4,datbytes);
894 decryptdata(bindat+6,datbytes-6);
899 outf = fopen(outname,"wb");
900 fwrite(bindat,datbytes,1,outf);
910 * fake file reading funcs
915 static void fakefopen(void)
922 static void fakegettoken(char *str)
928 start = (char *) str;
929 cptr = bindat+fakepos;
937 while (fakepos<fakemax && !isspace(c)) {
946 if(fakepos>fakemax) {
947 fprintf(stderr,"fromtype1: unexpected eof\n");
948 strcpy(start, "end");
952 static int fakefgets(char *buf,int max)
956 cptr = (char *)(bindat+fakepos);
960 if(*cptr == 10 || *cptr == 13)
969 static char *fakefread(int n)
972 return bindat+fakepos-n;
975 static void applymat(float mat[][2], float *x, float *y)
979 tx = ((*x)*mat[0][0])+((*y)*mat[0][1]);
980 ty = ((*x)*mat[1][0])+((*y)*mat[1][1]);
985 static void setcharlist(void)
990 for(i=0; i<NASCII; i++) ISOcharlist[i].prog = -1;
992 for(j=0; j<my_nchars; j++) {
993 name = my_charname[j];
996 for(i=0; i<NASCII; i++) {
997 if(ISOcharlist[i].name && (strcmp(name,ISOcharlist[i].name) == 0)){
998 ISOcharlist[i].prog = j;
1002 /*if (found == 0) printf("no match found for: %s\n", name);*/
1010 static objfnt * objfnt_from_psfont(PackedFile * pf)
1019 /* read the font matrix from the font */
1020 if (readfontmatrix(pf,mat)) return(0);
1022 /* decode the font data */
1023 decodetype1(pf, "/usr/tmp/type1.dec");
1025 /* open the input file */
1028 /* look for the /Subrs def and get my_nsubrs */
1030 if(!fakefgets(oneline,LINELEN)) {
1031 fprintf(stderr,"fromtype1: no /Subrs found\n");
1036 cptr = strchr(oneline,'/');
1038 if(strncmp(cptr,"/Subrs",6) == 0) {
1039 my_nsubrs = atoi(cptr+6);
1045 /* read the Subrs in one by one */
1046 for(i=0; i<my_nsubrs; i++)
1048 for(i=0; i<my_nsubrs; i++) {
1049 for(k=0; k<MAXTRIES; k++) {
1051 if(strcmp(tok,"dup") == 0)
1055 fprintf(stderr,"dup for subr %d not found in range\n", i);
1059 /* get the Subr index here */
1063 /* check to make sure it is in range */
1064 if(index<0 || index>my_nsubrs) {
1065 fprintf(stderr,"bad Subr index %d\n",index);
1069 /* get the number of bytes to read */
1074 /* read in the subroutine */
1075 my_sublen[index] = nread;
1076 my_subrs[index] = fakefread(nread);
1080 /* look for the CharStrings */
1083 cptr = strchr(tok,'/');
1084 if(cptr && strcmp(cptr,"/CharStrings") == 0)
1088 fakegettoken(tok); /* skip my_ncharscrings */
1089 fakegettoken(tok); /* skip dict */
1090 fakegettoken(tok); /* skip dup */
1091 fakegettoken(tok); /* skip begin */
1092 fakegettoken(tok); /* skip newline */
1094 /* read the CharStrings one by one */
1096 for(i=0; i<MAXCHARS; i++) {
1100 if(strcmp(tok,"end") == 0)
1103 /* get the char name and allocate space for it */
1104 namelen = strlen(tok);
1105 my_charname[i] = (char *)MEM_mallocN(namelen+1, "my_charname");
1106 strcpy(my_charname[i],tok);
1108 /* get the number of bytes to read */
1113 /* read in the char description */
1114 my_charlen[i] = nread;
1115 my_chars[i] = fakefread(nread);
1117 /* skip the end of line */
1123 /* decrypt the character descriptions */
1127 /* make the obj font */
1128 makeobjfont(savesplines);
1130 if (bindat) MEM_freeN(bindat);
1131 /* system("rm /usr/tmp/type1.dec"); */
1144 static void initpcstack(void)
1149 static void pushpc(char *pc)
1155 static char *poppc(void)
1159 fprintf(stderr,"\nYUCK: pc stack under flow\n");
1163 return pcstack[pcsp];
1167 * Data stack support
1171 static void initstack(void)
1176 static void push(int val)
1183 static int pop(void)
1187 fprintf(stderr,"\nYUCK: stack under flow\n");
1195 * call/return data stack
1199 static void initretstack(void)
1204 static void retpush(int val)
1207 retstack[retsp] = val;
1211 static int retpop(void)
1215 fprintf(stderr,"\nYUCK: ret stack under flow\n");
1219 return retstack[retsp];
1224 * execute the program:
1229 static void getmove(int *x, int *y)
1233 /* printf("ingetmove\n"); */
1236 static void getpos(int *x, int *y)
1242 static void subr1(void)
1248 static void subr2(void)
1254 fprintf(stderr,"subr2: bad poop\n");
1257 coordsave[coordpos][0] = x;
1258 coordsave[coordpos][1] = y;
1262 static void subr0(void)
1268 int xpos, ypos, noise;
1274 fprintf(stderr,"subr0: bad poop\n");
1277 x0 = coordsave[0][0];
1278 y0 = coordsave[0][1];
1280 x1 = coordsave[1][0]+x0;
1281 y1 = coordsave[1][1]+y0;
1282 x2 = coordsave[2][0];
1283 y2 = coordsave[2][1];
1284 x3 = coordsave[3][0];
1285 y3 = coordsave[3][1];
1286 rcurveto(x1,y1,x1+x2,y1+y2,x1+x2+x3,y1+y2+y3);
1287 x1 = coordsave[4][0];
1288 y1 = coordsave[4][1];
1289 x2 = coordsave[5][0];
1290 y2 = coordsave[5][1];
1291 x3 = coordsave[6][0];
1292 y3 = coordsave[6][1];
1293 rcurveto(x1,y1,x1+x2,y1+y2,x1+x2+x3,y1+y2+y3);
1300 static void append_poly_offset(short ofsx, short ofsy, short * data)
1304 if (data == 0) return;
1307 switch(chardata[nshorts++] = *data++) {
1309 nshorts --; /* for the first time */
1315 nverts = chardata[nshorts++] = *data++;
1317 chardata[nshorts++] = (*data++) + ofsx;
1318 chardata[nshorts++] = (*data++) + ofsy;
1324 static void append_spline_offset(short ofsx, short ofsy, short * data)
1328 if (data == 0) return;
1331 switch(chardata[nshorts++] = *data++) {
1339 case SP_RETCLOSEPATH:
1344 for (; nverts > 0; nverts--) {
1345 chardata[nshorts++] = (*data++) + ofsx;
1346 chardata[nshorts++] = (*data++) + ofsy;
1360 /* poly output stuff */
1362 static void setwidth(int w, int x)
1368 static void poly_beginchar(void)
1374 static void poly_endchar(void)
1377 chardata[nshorts++] = PO_RET;
1379 chardata[nshorts++] = PO_RETENDLOOP;
1382 static void poly_close(void)
1384 chardata[nvertpos] = npnts;
1388 static void poly_pnt(float x, float y)
1392 applymat(mat,&x,&y);
1397 chardata[nshorts++] = PO_BGNLOOP;
1398 nvertpos = nshorts++;
1400 chardata[nshorts++] = PO_ENDBGNLOOP;
1401 nvertpos = nshorts++;
1405 chardata[nshorts++] = ix;
1406 chardata[nshorts++] = iy;
1411 /* spline output stuff */
1413 static void spline_beginchar(void)
1419 static void spline_endchar(void)
1422 chardata[nshorts++] = SP_RET;
1424 chardata[nshorts++] = SP_RETCLOSEPATH;
1427 static void spline_close(void)
1429 chardata[nshorts++] = SP_CLOSEPATH;
1434 static void spline_line(float x0, float y0, float x1, float y1)
1436 applymat(mat,&x0,&y0);
1437 applymat(mat,&x1,&y1);
1440 chardata[nshorts++] = SP_MOVETO;
1441 chardata[nshorts++] = floor(x0);
1442 chardata[nshorts++] = floor(y0);
1446 chardata[nshorts++] = SP_LINETO;
1447 chardata[nshorts++] = floor(x1);
1448 chardata[nshorts++] = floor(y1);
1452 static void spline_curveto(float x0, float y0, float x1, float y1, float x2, float y2, float x3, float y3)
1454 applymat(mat,&x0,&y0);
1455 applymat(mat,&x1,&y1);
1456 applymat(mat,&x2,&y2);
1457 applymat(mat,&x3,&y3);
1460 chardata[nshorts++] = SP_MOVETO;
1461 chardata[nshorts++] = floor(x0);
1462 chardata[nshorts++] = floor(y0);
1466 chardata[nshorts++] = SP_CURVETO;
1467 chardata[nshorts++] = floor(x1);
1468 chardata[nshorts++] = floor(y1);
1469 chardata[nshorts++] = floor(x2);
1470 chardata[nshorts++] = floor(y2);
1471 chardata[nshorts++] = floor(x3);
1472 chardata[nshorts++] = floor(y3);
1475 static void savestart(int x, int y)
1482 static void sbpoint( int x, int y)
1488 static void rmoveto( int x, int y)
1496 savestart(curx,cury);
1500 static void drawline(float x0, float y0, float x1, float y1, float dx0, float dy0, float dx1, float dy1)
1502 if(x0!=x1 || y0!=y1)
1507 static void rlineto( int x, int y)
1515 if (savesplines) spline_line( curx, cury, nextx, nexty);
1516 else drawline( curx, cury, nextx, nexty,dx,dy,dx,dy);
1521 static void closepath(void)
1531 drawline( curx, cury, startx, starty,dx,dy,dx,dy);
1538 static void bezadapt( float x0, float y0, float x1, float y1, float x2, float y2, float x3, float y3, float beztol)
1540 float ax0,ay0,ax1,ay1,ax2,ay2,ax3,ay3;
1541 float bx0,by0,bx1,by1,bx2,by2,bx3,by3;
1543 float linx, liny, dx, dy, mag;
1545 midx = (x0+3*x1+3*x2+x3)/8.0;
1546 midy = (y0+3*y1+3*y2+y3)/8.0;
1552 if(mag<(beztol*beztol))
1553 drawline(x0,y0,x3,y3,x1-x0,y1-y0,x3-x2,y3-y2);
1559 ax2 = (x0+2*x1+x2)/4;
1560 ay2 = (y0+2*y1+y2)/4;
1563 bezadapt(ax0,ay0,ax1,ay1,ax2,ay2,ax3,ay3,beztol);
1567 bx1 = (x1+2*x2+x3)/4;
1568 by1 = (y1+2*y2+y3)/4;
1573 bezadapt(bx0,by0,bx1,by1,bx2,by2,bx3,by3,beztol);
1577 static void drawbez( float x0, float y0, float x1, float y1, float x2, float y2, float x3, float y3)
1579 bezadapt(x0,y0,x1,y1,x2,y2,x3,y3,beztol);
1583 static void rcurveto( int dx1, int dy1, int dx2, int dy2, int dx3, int dy3)
1600 spline_curveto( x0, y0, x1, y1, x2, y2, x3, y3);
1602 drawbez( x0, y0, x1, y1, x2, y2, x3, y3);
1610 * save an object font.
1614 /* generic routines */
1616 static void makeobjfont(int savesplines)
1621 fnt = newobjfnt(SP_TYPE, 32, 32+NASCII-1, 9840);
1623 fnt = newobjfnt(PO_TYPE, 32, 32+NASCII-1, 9840);
1625 for(i=0; i<NASCII; i++) {
1627 if(ISOcharlist[i].prog>=0) {
1628 /*printf("decoding %s\n", ISOcharlist[i].name);*/
1631 drawchar(ISOcharlist[i].prog);
1632 addchardata(fnt,c,chardata,nshorts);
1633 addcharmetrics(fnt,c,thecharwidth,0);
1634 sidebearing[c] = thesidebearing;
1635 } else if(c == ' ') {
1636 printf("faking space %d\n",i);
1637 fakechar(fnt,' ',400);
1643 * run the character program
1648 static void drawchar(int c)
1667 static int docommand(int cmd)
1669 int x, y, w, c1, c2;
1681 fprintf(stderr,"\nYUCK: WHAT0\n");
1686 /*printf("hstem: %d %d\n", pop(), pop());*/
1691 /*printf("vstem: %d %d\n", pop(), pop());*/
1717 rcurveto(dx1,dy1,dx1+dx2,dy1+dy2,dx1+dx2+dx3,dy1+dy2+dy3);
1724 subpc = my_subrs[sub];
1726 fprintf(stderr,"\nYUCK no sub addr\n");
1759 rcurveto(dx1,dy1,dx1+dx2,dy1+dy2,dx1+dx2+dx3,dy1+dy2+dy3);
1768 rcurveto(dx1,dy1,dx1+dx2,dy1+dy2,dx1+dx2+dx3,dy1+dy2+dy3);
1773 /*printf("vstem3\n");*/
1782 /*printf("hstem3\n");*/
1792 printf("seac: %3d %3d %3d %3d %3d\n", pop(), pop(), pop(), pop(), pop());
1794 c2 = STDtoISO(pop()); /* accent */
1795 c1 = STDtoISO(pop()); /* letter */
1797 cd = getchardesc(fnt, c1);
1799 memcpy(chardata, cd->data, cd->datalen);
1800 nshorts = cd->datalen / sizeof(short);
1803 cd = getchardesc(fnt, c2);
1804 if (cd && cd->data && cd->datalen) {
1809 switch (chardata[nshorts - 1]){
1813 case SP_RETCLOSEPATH:
1814 chardata[nshorts - 1] = SP_CLOSEPATH;
1818 switch (chardata[nshorts - 1]){
1820 printf("PO_RET in character disription ?\n");
1824 if (ndata[0] == PO_BGNLOOP) {
1825 chardata[nshorts - 1] = PO_ENDBGNLOOP;
1827 printf("new character doesn't start with PO_BGNLOOP ?\n");
1834 /* instead of the sidebearing[c1] maybe thesidebearing should be used */
1837 dx1 = pop() + sidebearing[c1] - sidebearing[c2];
1842 applymat(mat, &fdx1, &fdy1);
1847 append_spline_offset(dx1, dy1, ndata);
1849 append_poly_offset(dx1, dy1, ndata);
1852 /*printf("first: %d %d\n", cd->data[0], cd->data[1]);*/
1860 fprintf(stderr,"sbw: width: %d %d\n",w,y);
1863 fprintf(stderr,"sbw: side: %d %d\n",x,y);
1882 for(i=0; i<n; i++) {
1890 case SETCURRENTPOINT:
1896 /*fprintf(stderr,"\nYUCK bad instruction %d\n",cmd);*/
1899 if(pc == 0 || cmd == ENDCHAR || cmd == WHAT0 || cmd == SEAC)
1907 * Character interpreter
1911 static void runprog(void)
1923 if(!docommand(cmd)) {
1926 } else if(v>=32 && v<=246) {
1929 } else if(v>=247 && v<=250) {
1931 num = (v-247)*256+w+108;
1933 } else if(v>=251 && v<=254) {
1935 num = -(v-251)*256-w-108;
1937 } else if(v == 255) {
1952 static VFontData *objfnt_to_vfontdata(objfnt *fnt)
1956 short *_data, *data;
1957 int a, i, count, stop, ready, meet;
1958 short first[2], last[2];
1960 struct BezTriple *bezt, *bez2;
1961 float scale, dx, dy;
1963 if (!fnt || (fnt->type!=SP_TYPE)) {
1967 vfd= MEM_callocN(sizeof(*vfd), "VFontData");
1968 scale = 10.0/(float)fnt->scale; /* after IRIX 6.2, scaling went wrong */
1970 for (i = 0; i < MAX_VF_CHARS; i++) {
1971 cd = getchardesc(fnt, i);
1972 if (cd && cd->data && cd->datalen) {
1973 vfd->width[i] = scale * cd->movex;
1975 _data = data = cd->data;
2001 case SP_RETCLOSEPATH:
2011 if ((count>0) && last[0] == first[0] && last[1] == first[1]) meet = 1;
2014 /* is there more than 1 unique point ?*/
2016 if (count - meet > 0) {
2018 nu = (Nurb*)MEM_callocN(sizeof(struct Nurb),"objfnt_nurb");
2019 bezt = (BezTriple*)MEM_callocN((count)* sizeof(BezTriple),"objfnt_bezt") ;
2020 if (nu != 0 && bezt != 0) {
2021 BLI_addtail(&vfd->nurbsbase[i], nu);
2022 nu->type= CU_BEZIER+CU_2D;
2033 bezt->vec[1][0] = scale * *data++;
2034 bezt->vec[1][1] = scale * *data++;
2039 bezt->vec[1][0] = scale * *data++;
2040 bezt->vec[1][1] = scale * *data++;
2041 /* vector handles */
2044 dx = (bezt->vec[1][0] - bez2->vec[1][0]) / 3.0;
2045 dy = (bezt->vec[1][1] - bez2->vec[1][1]) / 3.0;
2046 bezt->vec[0][0] = bezt->vec[1][0] - dx;
2047 bezt->vec[0][1] = bezt->vec[1][1] - dy;
2048 bez2->vec[2][0] = bez2->vec[1][0] + dx;
2049 bez2->vec[2][1] = bez2->vec[1][1] + dy;
2053 bezt->vec[2][0] = scale * *data++;
2054 bezt->vec[2][1] = scale * *data++;
2057 bezt->vec[0][0] = scale * *data++;
2058 bezt->vec[0][1] = scale * *data++;
2059 bezt->vec[1][0] = scale * *data++;
2060 bezt->vec[1][1] = scale * *data++;
2065 case SP_RETCLOSEPATH:
2073 } while (stop == 0);
2077 nu->bezt->vec[0][0] = bezt->vec[0][0];
2078 nu->bezt->vec[0][1] = bezt->vec[0][1];
2079 /* and forget last point */
2083 /* vector handles */
2085 dx = (bezt->vec[1][0] - bez2->vec[1][0]) / 3.0;
2086 dy = (bezt->vec[1][1] - bez2->vec[1][1]) / 3.0;
2087 bezt->vec[2][0] = bezt->vec[1][0] - dx;
2088 bezt->vec[2][1] = bezt->vec[1][1] - dy;
2089 bez2->vec[0][0] = bez2->vec[1][0] + dx;
2090 bez2->vec[0][1] = bez2->vec[1][1] + dy;
2091 bezt->h2= bez2->h1= HD_VECT;
2094 /* forbidden handle combinations */
2098 if(bezt->h1!=HD_ALIGN && bezt->h2==HD_ALIGN) bezt->h2= 0;
2099 else if(bezt->h2!=HD_ALIGN && bezt->h1==HD_ALIGN) bezt->h1= 0;
2105 if (nu) MEM_freeN(nu);
2106 if (bezt) MEM_freeN(bezt);
2110 } while (ready == 0);
2117 VFontData *BLI_vfontdata_from_psfont(PackedFile *pf)
2119 objfnt *fnt= objfnt_from_psfont(pf);
2120 VFontData *vfd= NULL;
2123 vfd= objfnt_to_vfontdata(fnt);