source: trunk/pin/src/conv_afm.c@ 49

Last change on this file since 49 was 1, checked in by bart, 18 years ago

Initial checkin of PIN.EXE source code
this contains memory fixes for larger PPD files

File size: 70.2 KB
Line 
1/*DDK*************************************************************************/
2/* */
3/* COPYRIGHT Copyright (C) 1991, 2003 IBM Corporation */
4/* */
5/* The following IBM OS/2 source code is provided to you solely for */
6/* the purpose of assisting you in your development of OS/2 device */
7/* drivers. You may use this code in accordance with the IBM License */
8/* Agreement provided in the IBM Developer Connection Device Driver */
9/* Source Kit for OS/2. This Copyright statement may not be removed. */
10/* */
11/*****************************************************************************/
12
13// need full audit!
14// must eliminate RepWarning and RepError
15// declare all internal functions and variables static
16// remove outdated comments and code
17
18#pragma chars( signed )
19#pragma pack(1)
20/**************************************************************************
21 *
22 * SOURCE FILE NAME = AFM2BIN.C
23 *
24 * DESCRIPTIVE NAME = Metric File Compiler
25 *
26 *
27 * VERSION = V2.0
28 *
29 * DATE 02/25/88
30 *
31 * DESCRIPTION Converts an AFM fileand puts the output in an output file.
32 *
33 *
34 * FUNCTIONS
35 * report_warning
36 * report_error
37 * szIsEqual
38 * szMove
39 * GetBuffin
40 * UnGetLine
41 * EatWhite
42 * GetWord
43 * MapToken
44 * GetNumber
45 * GetFloat
46 * GetToken
47 * GetCharCode
48 * GetNextCharCode
49 * PrintLine
50 * CompareKPs
51 * ParseKernPairs
52 * ParseKernData
53 * ParseString
54 * ParseWeight
55 * ParseCharMetrics
56 * ParseCharBox
57 * ParseCharName
58 * ParseCharWidth
59 * ParseCharCode
60 * ParsePitchType
61 * OpenAfm
62 * FixCharWidths
63 * SetAfm
64 * ResetBuffout
65 * IncBuffout
66 * PutByte
67 * PutRgb
68 * PutWord
69 * PutDword
70 * PutString
71 * FillString
72 * WriteOutput
73 * AddExtension
74 * RemoveExtension
75 * GetArgs
76 * GetNextWord
77 * StrCopy
78 * ParseItalic
79 * ParseFamilyClass
80 *
81 * NOTES
82 *
83 * Format of the ".pfm" file generated:
84 * ====================================
85 *
86 * 1. Header (offsets to other sections)
87 * 2. Global font information
88 * 3. Character metrics
89 * 4. Pair Kerning data
90 * 5. Comment, Notice, etc. strings
91 * 6. Font metrics structure
92 *
93 *
94 * 1. Header
95 * ---------
96 * Offset Type
97 * 0000 word Version from StartFontMetrics
98 * (whole portion in high byte, fractional in low)
99 * 0002 word Offset to Global font information
100 * 0004 word Offset to Character metrics
101 * 0006 word Offset to Pair Kerning data
102 * 0008 word Offset to Strings section
103 * 000A word Offset to font metrics structure
104 * 000C word Size of the 5 above sections (global, metrics, etc.)
105 *
106 * Note: All sections (char metrics, kerning, etc) start on
107 * word-alinged boundaries.
108 *
109 *
110 *
111 * 2. Global font information
112 * --------------------------
113 * Offset Type
114 * 0000 word VariablePitch (ie, 1 for true, 0 for false)
115 * 0002 word*4 FontBBox
116 * 000A word CapHeight
117 *
118 *
119 *
120 * 3. Character metrics
121 * --------------------
122 * Offset Type
123 * 0000 byte Char code to output in a PostScript show command
124 * in order to display this character. 0=the font
125 * must be remapped in order to display this char,
126 * in which case just output the char directly.
127 * 0001 word Character width ("WX" argument)
128 * ......
129 *
130 *
131 *
132 * 4. Pair Kerning Data
133 * --------------------
134 * Offset Type
135 * 0000 word Char code 1
136 * 0002 word Char code 2
137 * 0004 word*2 Kerning vector ("KP/KPX" arguments)
138 * .....
139 * NOTE: If this font is codepage 850 (winthorn multi-codepage support)
140 * then the character codes above are actually the codes as
141 * remapped by the codepage vector -- presently in the range
142 * of 1-316.
143 *
144 *
145 *
146 * 5. Comment, Notice, Version, Fontname, EncodingString, and Weight strings
147 * -------------------------------------------------------------------------
148 * Offset Type
149 * 0000 asciiz FontName string (eg, "Times-RomanBold")
150 * asciiz Comment string
151 * asciiz Version string
152 * asciiz Notice string
153 * asciiz EncodingScheme (eg, "AdobeStandardEncoding")
154 * asciiz Weight (eg, "Bold")
155 *
156 *
157 *
158 * 6. Font metrics structure
159 * -------------------------
160 * CHAR szFamilyname[FACESIZE];
161 * CHAR szFacename[FACESIZE];
162 * SHORT idRegistry; / We always write as 0 /
163 * SHORT usCodePage; / 850 = Adobe standard encoding
164 * scheme; this font will
165 * offer winthorn multi-
166 * codepage support
167 * 0 = Adobe font-specific
168 * encoding; no multi-
169 * codepage support /
170 * LONG lEmHeight; / Height of emSquare (1000) /
171 * LONG lXHeight; / Height of lowercase x /
172 * LONG lMaxAscender; / Top of font bounding box /
173 * LONG lMaxDescender; / Bottom of font bounding box /
174 * LONG lLowerCaseAscent; / Top of tallest lowercase char /
175 * LONG lLowerCaseDescent; / Bottom of lowest lowercase descender /
176 * LONG lInternalLeading; / lMaxBaselineExt minus lEmHeight /
177 * LONG lExternalLeading; / Always zero /
178 * LONG lAveCharWidth; / Weighted average of char widths /
179 * LONG lMaxCharInc; / Widest character /
180 * LONG lEmInc; / Width of emSquare (1000) /
181 * LONG lMaxBaselineExt; / lMaxAscender + lMaxDescender /
182 * SHORT sCharSlope; / ItalicAngle field from afm file /
183 * SHORT sInlineDir; / 0 Degrees = left to right /
184 * SHORT sCharRot; / We always write as 0 /
185 * USHORT usWeightClass; / Font weight 1-9 /
186 * USHORT usWidthClass; / We always write as 5 (normal) /
187 * SHORT sXDeviceRes; / We always write as 1000 / !!CR
188 * SHORT sYDeviceRes; / We always write as 1000 / !!CR
189 * SHORT sFirstChar; / We always write as 1 /
190 * SHORT sLastChar; / For codepage 850, this is 316
191 * / For codepage 0, this is 255 /
192 * SHORT sDefaultChar; / We always write as 31 /
193 * SHORT sBreakChar; / We always write as 31 /
194 * SHORT sNominalPointSize; / We always write as 120 (12 pt.) /
195 * SHORT sMinimumPointSize; / We always write as 10 /
196 * SHORT sMaximumPointSize; / We always write as 7200 /
197 * USHORT fsType; / 0 = proportional, 1 = fixed /
198 * USHORT fsDefn; / 1 = outline /
199 * USHORT fsSelection; / We always write as 0 / !!CR
200 * USHORT fsCapabilities; / 0 = Can mix text and graphics /
201 * LONG lSubscriptXSize; / We always write as 0 /
202 * LONG lSubscriptYSize; / We always write as 0 /
203 * LONG lSubscriptXOffset; / We always write as 0 /
204 * LONG lSubscriptYOffset; / We always write as 0 /
205 * LONG lSuperscriptXSize; / We always write as 0 /
206 * LONG lSuperscriptYSize; / We always write as 0 /
207 * LONG lSuperscriptXOffset; / We always write as 0 /
208 * LONG lSuperscriptYOffset; / We always write as 0 /
209 * LONG lUnderscoreSize; / From afm file /
210 * LONG lUnderscorePosition; / From afm file /
211 * LONG lStrikeoutSize; / Based on hyphen character /
212 * LONG lStrikeoutPosition; / Based on hyphen character /
213 * SHORT sKerningPairs; / From afm file
214 * SHORT sFamilyClass; / Based on DCR 24415 /
215 * LONG lMatch; / We always write as 0 /
216 *
217 *
218 * STRUCTURES
219 *
220 * EXTERNAL REFERENCES
221 *
222 * EXTERNAL FUNCTIONS
223 *
224*/
225#include <os2.h>
226#include <stdio.h>
227#include <stdlib.h>
228#include <string.h>
229
230#include <ctype.h>
231//#include <search.h>
232/* #include <sys\types.h> */
233/* #include <sys\stat.h> */
234
235#include "afm.h"
236#include "mapping.h"
237
238BOOL fEcho = FALSE;
239BOOL fListStats = FALSE;
240BOOL fListMetrics = FALSE;
241BOOL fEOF = FALSE;
242BOOL fUnGetLine = FALSE;
243
244// Boolean flag to display all warnings, if TRUE (normally FALSE).
245BOOL FReportWarning = TRUE;
246
247FONTMETRICS fmFont;
248
249CharData *charmap; /* the conversion table from Adobe
250 character names into application
251 code points */
252AfmData afm;
253
254FILE *fhIn,*fhOut; /* file handles */
255char rgchIn[MAX_FNAMESIZE]; /* file names */
256char rgchOut[MAX_FNAMESIZE];
257
258SHORT cInline = 0;
259char rgbLine[MAX_LINESIZE]; /* current line of text being
260 processed */
261char *pszLine; /* ptr to the current location in the
262 line */
263SHORT cbBuffin; /* number of bytes in input buffer */
264char *pbBuffin; /* ptr to current location in input
265 buffer */
266char rgbBuffin[MAX_IBUFFSIZE];
267SHORT cbBuffout; /* number of bytes in output buffer */
268char *pbBuffout; /* ptr to current location in output
269 buffer */
270char rgbBuffout[MAX_OBUFFSIZE];
271#define ARBITRARY_CODEPAGE 65400 /* IBM CODEPAGE number for arbitrary
272 (/ /* glyphs */
273#define VOID void
274
275/*
276** Since this is used by the C runtime function qsort, this MUST be
277** defined as so to prevent the compiler from returning an error.
278*/
279int CompareKPs( const void *, const void * );
280VOID EatWhite( VOID );
281VOID FixCharWidths( VOID );
282BOOL GetBuffin( VOID );
283BOOL GetLine( VOID );
284SHORT GetNumber( VOID );
285SHORT GetToken( VOID );
286VOID OpenAfm( VOID );
287VOID ParseBaseFont( VOID );
288VOID ParseBoundingBox( VOID );
289VOID ParseCharBox( Rect * );
290SHORT ParseCharCode( VOID );
291VOID ParseCharMetrics( VOID );
292SHORT ParseCharWidth( VOID );
293VOID ParseFamilyClass( VOID );
294VOID ParseItalic( VOID );
295VOID ParseKernData( VOID );
296VOID ParseKernPairs( VOID );
297VOID ParsePitchType( VOID );
298VOID ParseWeight( VOID );
299VOID PrintLine( VOID );
300VOID ResetBuffout( VOID );
301VOID SetAfm( VOID );
302VOID UnGetLine( VOID );
303VOID WriteOutput( SHORT pass );
304VOID report_error( ErrType, char * );
305VOID report_warning( ErrType, char * );
306
307/***************************************************************************
308 *
309 * FUNCTION NAME = report_warning
310 *
311 * DESCRIPTION = prints the given message (err) with the given
312 * line fragment (pszLine), including the current
313 * input line number. If line fragment is NULL, then
314 * only the message is displayed.
315 *
316 * Display the warning message, only if '-w' is specified
317 * on the command line. This will cause FReportWarning to be
318 * set to TRUE.
319 *
320 * INPUT = err - index to error number
321 * pszLine - optional error text
322 *
323 * OUTPUT = NONE.
324 *
325 * RETURN-NORMAL = NONE.
326 * RETURN-ERROR = NONE.
327 *
328 ************************************************************************* */
329
330VOID report_warning(ErrType err,char *pszLineW)
331{
332
333 /*
334 ** Report warnings, only if '-w' was specified on the command line.
335 ** If FReportWarning == TRUE.
336 */
337 if (FReportWarning == TRUE)
338 {
339 if (cInline)
340 {
341 fprintf(stderr, "AFM2BIN: %s(%u): %s", rgchIn, cInline, errmsgs[err]);
342
343 if (pszLineW)
344 fprintf(stderr, " \"%s\"", pszLineW);
345 }
346
347 else
348 {
349 fprintf(stderr, "%s", errmsgs[err]);
350
351 if (pszLineW)
352 fprintf(stderr, " %s", pszLineW);
353 }
354 fprintf(stderr, "\n");
355
356 if (err == err_option || err == err_arg)
357 report_error(err_usage, NULL);
358 }
359}
360
361/***************************************************************************
362 *
363 * FUNCTION NAME = report_error
364 *
365 * DESCRIPTION = Same as report_warning, but terminates as well.
366 *
367 * INPUT = err - error number
368 * pszLine - optional text
369 *
370 * OUTPUT = NONE.
371 *
372 * RETURN-NORMAL = NONE.
373 * RETURN-ERROR = NONE
374 *
375 ************************************************************************* */
376
377VOID report_error( ErrType err, char *pszLineE )
378{
379 report_warning(err, pszLineE);
380 exit(1);
381}
382
383/***************************************************************************
384 *
385 * FUNCTION NAME = szIsEqual
386 *
387 * DESCRIPTION = Compares two NULL terminated strings.
388 *
389 * INPUT = sz1 - character string 1
390 * sz2 - character string 2
391 *
392 * OUTPUT = NONE.
393 *
394 * RETURN-NORMAL = Returns TRUE if they are equal,
395 * RETURN-ERROR = FALSE if they are different.
396 *
397 ************************************************************************* */
398
399BOOL szIsEqual(char *sz1,char *sz2)
400{
401
402 while (*sz1 && *sz2)
403 {
404
405 if (*sz1++ != *sz2++)
406 return (FALSE);
407 }
408 return (*sz1 == *sz2);
409}
410
411/***************************************************************************
412 *
413 * FUNCTION NAME = szMove
414 *
415 * DESCRIPTION = Copies a string. This function will copy at most
416 * the number of bytes in the destination area - 1.
417 *
418 * INPUT = szDest - destination string
419 * szSrc - source string
420 * cbDst - size of destination string
421 *
422 * OUTPUT = NONE.
423 *
424 * RETURN-NORMAL = NONE.
425 * RETURN-ERROR = NONE.
426 *
427 ************************************************************************* */
428
429VOID szMove(char *szDst,char *szSrc,SHORT cbDst)
430{
431
432 while (*szDst++ = *szSrc++)
433
434 if (--cbDst <= 0)
435 {
436 *(szDst-1) = 0;
437 break;
438 }
439}
440
441/***************************************************************************
442 *
443 * FUNCTION NAME = GetBuffin
444 *
445 * DESCRIPTION = Read a new buffer full of text from the input file.
446 *
447 * Note: If the end of file is encountered in this function
448 * then the program is aborted with an error message.
449 * Normally the program will stop processing the input
450 * when it sees the end of information keyword.
451 *
452 * INPUT = input file.
453 * OUTPUT = NONE.
454 *
455 * RETURN-NORMAL = NONE.
456 * RETURN-ERROR = NONE.
457 *
458 ************************************************************************* */
459
460BOOL GetBuffin( VOID )
461{
462 cbBuffin = 0;
463
464 if (!fEOF)
465 {
466 cbBuffin = fread( rgbBuffin, 1, sizeof(rgbBuffin), fhIn );
467
468 if (cbBuffin <= 0)
469 {
470 cbBuffin = 0;
471 fEOF = TRUE;
472 report_error(err_eof, NULL);
473 }
474 }
475 pbBuffin = rgbBuffin;
476 return (fEOF);
477}
478
479/***************************************************************************
480 *
481 * FUNCTION NAME = UnGetLine
482 *
483 * DESCRIPTION = This routine pushes the most recent line back into
484 * the input buffer.
485 *
486 * INPUT = NONE.
487 * OUTPUT = Line back into the input stream.
488 *
489 * RETURN-NORMAL = NONE.
490 * RETURN-ERROR = NONE.
491 *
492 ************************************************************************* */
493
494VOID UnGetLine( VOID )
495{
496 cInline--;
497 fUnGetLine = TRUE;
498 pszLine = rgbLine;
499}
500
501/***************************************************************************
502 *
503 * FUNCTION NAME = GetLine
504 *
505 * DESCRIPTION = This routine gets the next line of text out of the
506 * input buffer.
507 *
508 * INPUT = NONE.
509 * OUTPUT = NONE.
510 *
511 * RETURN-NORMAL = End of File.
512 * RETURN-ERROR = NONE.
513 *
514 ************************************************************************* */
515
516BOOL GetLine( VOID )
517{
518 SHORT cbLine;
519 char bCh;
520 cInline++;
521
522
523 if (fUnGetLine)
524 {
525 pszLine = rgbLine;
526 fUnGetLine = FALSE;
527 return (FALSE);
528 }
529 cbLine = 0;
530 pszLine = rgbLine;
531 *pszLine = 0;
532
533 if (!fEOF)
534 {
535
536 while (TRUE)
537 {
538
539 if (cbBuffin <= 0)
540 GetBuffin();
541
542 while (--cbBuffin >= 0)
543 {
544 bCh = *pbBuffin++;
545
546 if (bCh == '\n' || ++cbLine > (SHORT)sizeof(rgbLine))
547 {
548 *pszLine = 0;
549 pszLine = rgbLine;
550 EatWhite();
551
552 if (*pszLine != 0)
553 goto DONE;
554
555 pszLine = rgbLine;
556 cbLine = 0;
557 continue;
558 }
559 *pszLine++ = bCh;
560 }
561 }
562 }
563 *pszLine = 0;
564DONE:
565 pszLine = rgbLine;
566 return (fEOF);
567}
568
569/***************************************************************************
570 *
571 * FUNCTION NAME = EatWhite
572 *
573 * DESCRIPTION = This routine moves the input buffer pointer forward
574 * to the next non-white character.
575 *
576 * INPUT = NONE.
577 * OUTPUT = NONE.
578 *
579 * RETURN-NORMAL = NONE.
580 * RETURN-ERROR = NONE.
581 *
582 ************************************************************************* */
583
584VOID EatWhite( VOID )
585{
586
587 while (*pszLine && (*pszLine == ' ' || *pszLine == '\t'))
588 ++pszLine;
589}
590
591/***************************************************************************
592 *
593 * FUNCTION NAME = GetWord
594 *
595 * DESCRIPTION = This routine gets the next word delimited by white
596 * space from the input buffer.
597 *
598 * INPUT = szWord - destination
599 * cbWord - size of destination
600 *
601 * OUTPUT = NONE.
602 *
603 * RETURN-NORMAL = NONE.
604 * RETURN-ERROR = NONE.
605 *
606 ************************************************************************* */
607
608VOID GetWord(char *szWord,SHORT cbWord)
609{
610 char bCh;
611
612 EatWhite();
613
614 while (--cbWord > 0)
615 {
616
617 switch (bCh = *pszLine++)
618 {
619 case 0 :
620 --pszLine;
621 goto DONE;
622
623 case ' ' :
624 case '\t' :
625 --pszLine;
626 goto DONE;
627
628 case ';' :
629 *szWord++ = bCh;
630 goto DONE;
631 default :
632
633 *szWord++ = bCh;
634 break;
635 }
636 }
637DONE:
638 *szWord = 0;
639}
640
641/***************************************************************************
642 *
643 * FUNCTION NAME = MapToken
644 *
645 * DESCRIPTION = This routine maps an ascii key word into an
646 * enumerated token.
647 *
648 * INPUT = szWord - ptr to the ASCII keyword string
649 *
650 * OUTPUT = NONE.
651 *
652 * RETURN-NORMAL = The token value
653 * RETURN-ERROR = Token Unknown
654 *
655 ************************************************************************* */
656
657TokType MapToken(char *szWord)
658{
659 TokType iToken = 0;
660
661
662 while (iToken < tok_max)
663 {
664
665 if (szIsEqual(szWord, tokens[iToken]))
666 return (iToken);
667 ++iToken;
668 }
669 return (tok_unknown);
670}
671
672/***************************************************************************
673 *
674 * FUNCTION NAME = GetNumber
675 *
676 * DESCRIPTION = This routine parses an ASCII decimal number from the
677 * input file stream and returns its value.
678 *
679 * INPUT = NONE.
680 * OUTPUT = NONE.
681 *
682 * RETURN-NORMAL = Number Value.
683 * RETURN-ERROR = NONE.
684 *
685 ************************************************************************* */
686
687SHORT GetNumber( VOID )
688{
689 SHORT iVal;
690 BOOL fNegative;
691
692 fNegative = FALSE;
693 iVal = 0;
694 EatWhite();
695
696 if (*pszLine == '-')
697 {
698 fNegative = TRUE;
699 ++pszLine;
700 }
701
702 if (*pszLine < '0' || *pszLine > '9')
703 report_error(err_badnum, pszLine);
704
705 while (*pszLine >= '0' && *pszLine <= '9')
706 iVal = iVal *10+(*pszLine++-'0');
707
708 if (fNegative)
709 iVal = -iVal;
710
711 if (*pszLine == 0 || *pszLine == ' ' || *pszLine == '\t' || *pszLine == ';')
712 return (iVal);
713
714 return (0);
715}
716
717/***************************************************************************
718 *
719 * FUNCTION NAME = GetFloat
720 *
721 * DESCRIPTION = This routine parses an ASCII floating point decimal
722 * number from the input file stream and returns its
723 * value scaled by a specified amount.
724 *
725 * INPUT = iScale - amount to scale the value by
726 * OUTPUT = NONE.
727 *
728 * RETURN-NORMAL = value
729 * RETURN-ERROR = NONE.
730 *
731 ************************************************************************* */
732
733SHORT GetFloat(SHORT iScale)
734{
735 long lVal;
736 long lDivisor;
737 BOOL fNegative;
738
739 EatWhite();
740 fNegative = FALSE;
741 lVal = 0L;
742
743 if (*pszLine == '-')
744 {
745 fNegative = TRUE;
746 ++pszLine;
747 }
748
749 if (*pszLine < '0' || *pszLine > '9')
750 report_error(err_badreal, pszLine);
751
752 while (*pszLine >= '0' && *pszLine <= '9')
753 lVal = lVal *10+(*pszLine++-'0');
754 lDivisor = 1L;
755
756 if (*pszLine == '.')
757 {
758 ++pszLine;
759
760 while (*pszLine >= '0' && *pszLine <= '9')
761 {
762 lVal = lVal *10+(*pszLine++-'0');
763 lDivisor = lDivisor *10;
764 }
765 }
766 lVal = (lVal *iScale)/lDivisor;
767
768 if (fNegative)
769 lVal = -lVal;
770
771 if (*pszLine == 0 || *pszLine == ' ' || *pszLine == '\t' || *pszLine == ';')
772 return ((short)lVal);
773
774 return(0);
775}
776
777/***************************************************************************
778 *
779 * FUNCTION NAME = GetToken
780 *
781 * DESCRIPTION = Get the next token from the input stream.
782 *
783 * INPUT = NONE.
784 * OUTPUT = NONE.
785 *
786 * RETURN-NORMAL = NONE.
787 * RETURN-ERROR = NONE.
788 *
789 ************************************************************************* */
790
791SHORT GetToken( VOID )
792{
793 char szWord[80];
794
795
796 if (*pszLine == 0)
797
798 if (GetLine())
799 return (tok_max);
800 GetWord(szWord, sizeof(szWord));
801 return (MapToken(szWord));
802}
803
804/***************************************************************************
805 *
806 * FUNCTION NAME = GetCharCode
807 *
808 * DESCRIPTION = Given a name of a Postscript character, this
809 * function determines what its code point shall be
810 * (in the sense of winthorn multi- code page support)
811 * and what character code must be output in a
812 * Postscript "show" command in order to display this
813 * character. If the latter is zero, then a complete
814 * Postscript font remapping is necessary in order to
815 * display this character.
816 *
817 * INPUT = pcd - postscript character definition pointer
818 * OUTPUT = NONE.
819 *
820 * RETURN-NORMAL = NONE.
821 * RETURN-ERROR = NONE.
822 *
823 ************************************************************************* */
824
825void GetCharCode(CharData *pcd)
826{
827 register CharData *p;
828
829 p = charmap;
830
831 while (p->pszName)
832 {
833
834 if (szIsEqual(pcd->pszName, p->pszName))
835 {
836 pcd->iCP850Code = p->iCP850Code;
837 pcd->ipscriptCode = p->ipscriptCode;
838 return ;
839 }
840 ++p;
841 }
842
843// report_warning(err_unkchar, pcd->pszName);
844
845 pcd->iCP850Code = 0;
846 return ;
847}
848
849/***************************************************************************
850 *
851 * FUNCTION NAME = GetNextCharCode
852 *
853 * DESCRIPTION = This is similar to GetCharCode() above. But one
854 * Adobe character name may map to several code page
855 * 850 code points. This function continues scanning
856 * the list and returns matches until the end of the
857 * list is reached, at which time a null pointer is
858 * returned.
859 *
860 * INPUT = pcd - pcd pointer
861 * pcdRemainingList - list of pcds
862 *
863 *
864 * OUTPUT =
865 *
866 * RETURN-NORMAL =
867 * RETURN-ERROR =
868 *
869 ************************************************************************* */
870
871CharData *GetNextCharCode(CharData *pcd,CharData *pcdRemainingList)
872{
873 register CharData *p;
874
875 p = pcdRemainingList;
876
877 while (p != NULL && p->pszName)
878 {
879
880 if (szIsEqual(pcd->pszName, p->pszName))
881 {
882 pcd->iCP850Code = p->iCP850Code;
883 pcd->ipscriptCode = p->ipscriptCode;
884 return (p+1);
885 }
886 ++p;
887 }
888 pcd->iCP850Code = 0;
889 return (0);
890}
891
892/***************************************************************************
893 *
894 * FUNCTION NAME = PrintLine
895 *
896 * DESCRIPTION = Print a line of ASCII text with the white space
897 * stripped out.
898 *
899 * INPUT = NONE.
900 * OUTPUT = NONE.
901 *
902 * RETURN-NORMAL = NONE.
903 * RETURN-ERROR = NONE.
904 *
905 ************************************************************************* */
906
907VOID PrintLine( VOID )
908{
909 char szWord[80];
910
911
912 while (*pszLine)
913 {
914 GetWord(szWord, sizeof(szWord));
915 printf("%s ", szWord);
916 }
917 printf("\n");
918}
919
920/***************************************************************************
921 *
922 * FUNCTION NAME = CompareKPs
923 *
924 * DESCRIPTION = Returns a comparison of two kern pairs.
925 *
926 * INPUT = pKP1 - pointer to Kerning Pair 1
927 * pKP2 - pointer to Kerning Pair 2
928 *
929 * OUTPUT = NONE.
930 *
931 * RETURN-NORMAL = NONE.
932 * RETURN-ERROR = NONE.
933 *
934 ************************************************************************* */
935int CompareKPs( const void *pKP1, const void *pKP2 )
936{
937 return( (int) (((KPair *) pKP1)->iKey1 - ((KPair *) pKP2)->iKey1) );
938}
939
940/***************************************************************************
941 *
942 * FUNCTION NAME = ParseKernPairs
943 *
944 * DESCRIPTION = Parse the pairwise kerning data.
945 *
946 * INPUT = NONE.
947 * OUTPUT = NONE.
948 *
949 * RETURN-NORMAL = NONE.
950 * RETURN-ERROR = NONE.
951 *
952 ************************************************************************* */
953
954VOID ParseKernPairs( VOID )
955{
956 SHORT i;
957 SHORT iCh1;
958 SHORT iCh2;
959 TokType iToken;
960 SHORT cPairs;
961 char szWord[80];
962 CharData cd1,cd2;
963
964 cPairs = GetNumber();
965 i = 0;
966
967 while (i < cPairs)
968 {
969
970 if (GetLine())
971 break;
972
973 if (GetToken() != tok_kpx)
974 {
975 UnGetLine();
976 break;
977 }
978 GetWord(szWord, sizeof(szWord));
979 cd1.pszName = szWord;
980 GetCharCode(&cd1);
981 iCh1 = cd1.ipscriptCode;
982 GetWord(szWord, sizeof(szWord));
983 cd2.pszName = szWord;
984 GetCharCode(&cd2);
985 iCh2 = cd2.ipscriptCode;
986
987 /*
988 ** If either character is not in codepage 850 then throw away this
989 ** kerning pair.
990 */
991
992 if (iCh1 == 0 || iCh2 == 0)
993 {
994 --cPairs;
995 continue;
996 }
997 afm.rgKPairs[i].sAmount = GetNumber();
998 afm.rgKPairs[i].iKey1 = iCh1;
999 afm.rgKPairs[i].iKey2 = iCh2;
1000 ++i;
1001 }
1002 fmFont.sKerningPairs = afm.cKPairs = cPairs;
1003 GetLine();
1004 iToken = GetToken();
1005
1006 if (fEOF)
1007 report_error(err_eofin, tokens[tok_startkernpairs]);
1008
1009 else
1010
1011 if (iToken != tok_endkernpairs)
1012 report_error(err_expected, tokens[tok_endkernpairs]);
1013 qsort( &afm.rgKPairs[0], afm.cKPairs, sizeof( KPair ), CompareKPs );
1014}
1015
1016/***************************************************************************
1017 *
1018 * FUNCTION NAME = ParseKernData
1019 *
1020 * DESCRIPTION = Start processing the pairwise kerning data.
1021 *
1022 *
1023 * INPUT = NONE.
1024 * OUTPUT = NONE.
1025 *
1026 * RETURN-NORMAL = NONE.
1027 * RETURN-ERROR = NONE.
1028 *
1029 ************************************************************************* */
1030
1031VOID ParseKernData( VOID )
1032{
1033
1034 if (!GetLine())
1035 {
1036
1037 if (GetToken() == tok_startkernpairs)
1038 ParseKernPairs();
1039
1040 else
1041 report_warning(err_expected, tokens[tok_startkernpairs]);
1042 }
1043
1044 else
1045 report_warning(err_eof, NULL);
1046}
1047
1048/***************************************************************************
1049 *
1050 * FUNCTION NAME = ParseString
1051 *
1052 * DESCRIPTION = Move the next string from the input buffer into the
1053 * afm structure.
1054 *
1055 * INPUT = psz - destination string
1056 * maxsize - maximum size of destination string
1057 *
1058 * OUTPUT = NONE.
1059 *
1060 * RETURN-NORMAL = NONE.
1061 * RETURN-ERROR = NONE.
1062 *
1063 ************************************************************************* */
1064
1065VOID ParseString(char *psz,SHORT maxsize)
1066{
1067 EatWhite();
1068 szMove(psz, pszLine, maxsize);
1069}
1070
1071/***************************************************************************
1072 *
1073 * FUNCTION NAME = ParseWeight
1074 *
1075 * DESCRIPTION = Parse the fonts weight and set the corresponding entry
1076 * in the afm structure.
1077 *
1078 * INPUT = NONE.
1079 * OUTPUT = NONE.
1080 *
1081 * RETURN-NORMAL = NONE.
1082 * RETURN-ERROR = NONE.
1083 *
1084 ************************************************************************* */
1085
1086VOID ParseWeight( VOID )
1087{
1088 char szWord[80];
1089
1090 GetWord(szWord, sizeof(szWord));
1091
1092 if (szIsEqual(szWord, "Medium") || szIsEqual(szWord, "Roman") || szIsEqual
1093 (szWord, "Regular") || szIsEqual(szWord, "MediumCondensed"))
1094 fmFont.usWeightClass = FW_NORMAL;
1095
1096 else
1097
1098 if (szIsEqual(szWord, "Bold") || szIsEqual(szWord, "BoldCondensed"))
1099 fmFont.usWeightClass = FW_BOLD;
1100
1101 else
1102
1103 if (szIsEqual(szWord, "Demi"))
1104 fmFont.usWeightClass = FW_SEMIBOLD;
1105
1106 else
1107
1108 if (szIsEqual(szWord, "Light"))
1109 fmFont.usWeightClass = FW_LIGHT;
1110
1111 else
1112
1113 if (szIsEqual(szWord, "Book"))
1114 fmFont.usWeightClass = FW_SEMILIGHT;
1115
1116 else
1117
1118 if (szIsEqual(szWord, "Black"))
1119 fmFont.usWeightClass = FW_ULTRABOLD;
1120
1121 else
1122 report_warning(err_unkfontw, szWord);
1123 szMove(afm.szWeight, szWord, sizeof(szWord));
1124}
1125
1126/***************************************************************************
1127 *
1128 * FUNCTION NAME = ParseCharMetrics
1129 *
1130 * DESCRIPTION = Parse the character metrics entry in the input file
1131 * and set the width and bounding box in the afm structure.
1132 *
1133 * INPUT = NONE.
1134 * OUTPUT = NONE.
1135 *
1136 * RETURN-NORMAL = NONE.
1137 * RETURN-ERROR = NONE.
1138 *
1139 ************************************************************************* */
1140
1141VOID ParseCharMetrics( VOID )
1142{
1143 SHORT cChars;
1144 SHORT i;
1145 SHORT iWdth;
1146 SHORT iChar;
1147 long MWidth;
1148 long MHeight;
1149 long MRatio;
1150 Rect rcChar;
1151 CharData cd;
1152 char szName[20];
1153 CharData *pcdNext;
1154
1155 cChars = GetNumber();
1156
1157 for (i = 0; i < cChars; ++i)
1158 {
1159
1160 if (GetLine())
1161 report_error(err_eofin, tokens[tok_startcharmetrics]);
1162 iChar = ParseCharCode();
1163 iWdth = ParseCharWidth();
1164
1165 if (iWdth > (int)fmFont.lMaxCharInc)
1166 fmFont.lMaxCharInc = (LONG)iWdth;
1167 cd.pszName = szName;
1168 pcdNext = ParseCharName(&cd);
1169 ParseCharBox(&rcChar);
1170
1171 /*
1172 ** get the size of M square for the font. from this we will
1173 ** get the relative width of the font and fill in the
1174 ** font metrics usWidthClass field.
1175 */
1176
1177 if (!strcmp(cd.pszName, "M"))
1178 {
1179 MWidth = (long)(rcChar.right-rcChar.left);
1180 MHeight = (long)(rcChar.top-rcChar.bottom);
1181
1182 /*
1183 ** now get the width/height ratio.
1184 */
1185
1186 MRatio = (MWidth *100L)/MHeight;
1187
1188 if (MRatio <= 50L)
1189 fmFont.usWidthClass = ULTRACONDENSED;
1190
1191 else
1192
1193 if (MRatio <= 63L)
1194 fmFont.usWidthClass = EXTRACONDENSED;
1195
1196 else
1197
1198 if (MRatio <= 75L)
1199 fmFont.usWidthClass = CONDENSED;
1200
1201 else
1202
1203 if (MRatio <= 88L)
1204 fmFont.usWidthClass = SEMICONDENSED;
1205
1206 else
1207
1208 if (MRatio <= 112l)
1209 fmFont.usWidthClass = MEDIUM;
1210
1211 else
1212
1213 if (MRatio <= 124L)
1214 fmFont.usWidthClass = SEMIEXPANDED;
1215
1216 else
1217
1218 if (MRatio <= 149L)
1219 fmFont.usWidthClass = EXPANDED;
1220
1221 else
1222
1223 if (MRatio <= 199L)
1224 fmFont.usWidthClass = EXTRAEXPANDED;
1225
1226 else
1227 fmFont.usWidthClass = ULTRAEXPANDED;
1228 }
1229
1230 /*
1231 ** If this character is the hyphen, extract some
1232 ** info for the font metrics "strikeout" fields.
1233 */
1234
1235 if (!strcmp(cd.pszName, "hyphen"))
1236 {
1237 fmFont.lStrikeoutSize = rcChar.top-rcChar.bottom;
1238 fmFont.lStrikeoutPosition = (rcChar.top+rcChar.bottom)/2;
1239 }
1240
1241 do
1242 {
1243
1244 if (fListStats)
1245 printf("\042%s\042 maps to code point %d\n", cd.pszName, cd.iCP850Code)
1246 ;
1247 afm.rgcm[cd.iCP850Code].ipscriptCode = cd.ipscriptCode;
1248 afm.rgcm[cd.iCP850Code].cvec.x = iWdth;
1249 afm.rgcm[cd.iCP850Code].cvec.y = 0;
1250 afm.rgcm[cd.iCP850Code].rc.top = rcChar.top;
1251 afm.rgcm[cd.iCP850Code].rc.left = rcChar.left;
1252 afm.rgcm[cd.iCP850Code].rc.right = rcChar.right;
1253 afm.rgcm[cd.iCP850Code].rc.bottom = rcChar.bottom;
1254 pcdNext = GetNextCharCode(&cd, pcdNext);
1255 }
1256
1257 while (pcdNext);
1258 }
1259 GetLine();
1260
1261 if (GetToken() != tok_endcharmetrics)
1262 report_error(err_expected, tokens[tok_endcharmetrics]);
1263}
1264
1265/***************************************************************************
1266 *
1267 * FUNCTION NAME = ParseCharBox
1268 *
1269 * DESCRIPTION = Parse the character's bounding box and return its
1270 * dimensions in the destination rectangle.
1271 *
1272 * INPUT = prc - pointer to the destination rectangle
1273 *
1274 * OUTPUT = NONE.
1275 *
1276 * RETURN-NORMAL = NONE.
1277 * RETURN-ERROR = NONE.
1278 *
1279 ************************************************************************* */
1280
1281VOID ParseCharBox( Rect *prc )
1282{
1283 char szWord[16];
1284
1285 GetWord(szWord, sizeof(szWord));
1286
1287 if (szIsEqual("B", szWord))
1288 {
1289 prc->left = GetNumber();
1290 prc->bottom = GetNumber();
1291 prc->right = GetNumber();
1292 prc->top = GetNumber();
1293 }
1294
1295 else
1296 report_error(err_missingbbox, NULL);
1297 EatWhite();
1298
1299 if (*pszLine++ != ';')
1300 report_error(err_missingsemi, NULL);
1301}
1302
1303/***************************************************************************
1304 *
1305 * FUNCTION NAME = ParseCharName
1306 *
1307 * DESCRIPTION = Parse a character's name and return its name and
1308 * numeric values. Also return a pointer into the
1309 * character list to show how much of the list has
1310 * already been scanned.
1311 *
1312 * INPUT = pcd
1313 * OUTPUT = NONE.
1314 *
1315 * RETURN-NORMAL = NONE.
1316 * RETURN-ERROR = NONE.
1317 *
1318 ************************************************************************* */
1319
1320CharData *ParseCharName(CharData *pcd)
1321{
1322 register CharData *p;
1323
1324 EatWhite();
1325 GetWord(pcd->pszName, 16);
1326
1327 if (szIsEqual("N", pcd->pszName))
1328 {
1329 GetWord(pcd->pszName, 16);
1330 GetCharCode(pcd);
1331 }
1332
1333 else
1334 report_error(err_expectedname, NULL);
1335 EatWhite();
1336
1337 if (*pszLine++ != ';')
1338 report_error(err_missingsemi, NULL);
1339 p = charmap;
1340
1341 while (p->pszName)
1342 {
1343
1344 if (szIsEqual(pcd->pszName, p->pszName))
1345 {
1346 return (p+1);
1347 }
1348 ++p;
1349 }
1350 return (0);
1351}
1352
1353/***************************************************************************
1354 *
1355 * FUNCTION NAME = ParseCharWidth
1356 *
1357 * DESCRIPTION = Parse a character's width and return its numeric value.
1358 *
1359 * INPUT = NONE.
1360 * OUTPUT = NONE.
1361 *
1362 * RETURN-NORMAL = NONE.
1363 * RETURN-ERROR = NONE.
1364 *
1365 ************************************************************************* */
1366
1367SHORT ParseCharWidth( VOID )
1368{
1369 char szWord[16];
1370 register SHORT iWdth;
1371
1372 GetWord(szWord, sizeof(szWord));
1373
1374 if (szIsEqual(tokens[tok_wx], szWord))
1375 {
1376 iWdth = GetNumber();
1377
1378 if (iWdth == 0)
1379 report_error(err_zerocharw, NULL);
1380 EatWhite();
1381
1382 if (*pszLine++ != ';')
1383 report_error(err_missingsemi, NULL);
1384 }
1385
1386 else
1387 report_error(err_expected, tokens[tok_wx]);
1388 return (iWdth);
1389}
1390
1391/***************************************************************************
1392 *
1393 * FUNCTION NAME = ParseCharCode
1394 *
1395 * DESCRIPTION = Parse the ascii form of a character's code point and
1396 * return its numeric value.
1397 *
1398 * INPUT = NONE.
1399 * OUTPUT = NONE.
1400 *
1401 * RETURN-NORMAL = NONE.
1402 * RETURN-ERROR = NONE.
1403 *
1404 ************************************************************************* */
1405
1406SHORT ParseCharCode( VOID )
1407{
1408 SHORT iChar;
1409 char szWord[16];
1410
1411 iChar = 0;
1412 GetWord(szWord, sizeof(szWord));
1413
1414 if (szIsEqual("C", szWord))
1415 {
1416 iChar = GetNumber();
1417
1418 if (iChar == 0)
1419 report_error(err_badccode, NULL);
1420 EatWhite();
1421
1422 if (*pszLine++ != ';')
1423 report_error(err_missingsemi, NULL);
1424 }
1425 return (iChar);
1426}
1427
1428/***************************************************************************
1429 *
1430 * FUNCTION NAME = ParseBounding Box
1431 *
1432 * DESCRIPTION = Parse a character's bounding box and return its size
1433 * in the afm structure.
1434 *
1435 * INPUT = NONE.
1436 * OUTPUT = NONE.
1437 *
1438 * RETURN-NORMAL = NONE.
1439 * RETURN-ERROR = NONE.
1440 *
1441 ************************************************************************* */
1442
1443VOID ParseBoundingBox( VOID )
1444{
1445 afm.rcBBox.left = GetNumber();
1446 afm.rcBBox.bottom = GetNumber();
1447 afm.rcBBox.right = GetNumber();
1448 afm.rcBBox.top = GetNumber();
1449 fmFont.lMaxAscender = (LONG)afm.rcBBox.top;
1450 fmFont.lMaxDescender = (LONG)abs(afm.rcBBox.bottom);
1451 fmFont.lInternalLeading = (fmFont.lMaxAscender+fmFont.lMaxDescender)-1000;
1452}
1453
1454/***************************************************************************
1455 *
1456 * FUNCTION NAME = ParsePitchType
1457 *
1458 * DESCRIPTION = Parse the pitch type and set the variable pitch
1459 * flag in the afm structure.
1460 *
1461 * INPUT = NONE.
1462 * OUTPUT = NONE.
1463 *
1464 * RETURN-NORMAL = NONE.
1465 * RETURN-ERROR = NONE.
1466 *
1467 ************************************************************************* */
1468
1469VOID ParsePitchType( VOID )
1470{
1471 char szWord[16];
1472
1473 EatWhite();
1474 GetWord(szWord, sizeof(szWord));
1475
1476 if (szIsEqual("true", szWord))
1477 {
1478 afm.fVariablePitch = FALSE;
1479// fmFont.fsType = 1; //@DBCS
1480 fmFont.fsType |= FM_TYPE_FIXED; //@DBCS
1481 }
1482
1483 else
1484 {
1485 afm.fVariablePitch = TRUE;
1486// fmFont.fsType = 0; //@DBCS
1487 fmFont.fsType &=~ FM_TYPE_FIXED; //@DBCS
1488 }
1489}
1490
1491/***************************************************************************
1492 *
1493 * FUNCTION NAME = OpenAfm
1494 *
1495 * DESCRIPTION = Initialize the afm structure, and open the files.
1496 *
1497 * INPUT = NONE.
1498 * OUTPUT = NONE.
1499 *
1500 * RETURN-NORMAL = NONE.
1501 * RETURN-ERROR = NONE.
1502 *
1503 ************************************************************************* */
1504
1505VOID OpenAfm( VOID )
1506{
1507 SHORT i;
1508
1509 /*
1510 ** global stuff
1511 */
1512
1513 afm.iMaxWidth = 0;
1514 afm.version = 0;
1515 afm.szFontName[0] = 0;
1516 afm.szComment[0] = 0;
1517 afm.fVariablePitch = FALSE;
1518 fmFont.idRegistry = 0;
1519 fmFont.usCodePage = CODE_PAGE;
1520 fmFont.lEmHeight = 1000L;
1521 fmFont.lXHeight = 0L;
1522 fmFont.lMaxAscender = 0L;
1523 fmFont.lMaxDescender = 0L;
1524 fmFont.lLowerCaseAscent = 0L;
1525 fmFont.lLowerCaseDescent = 0L;
1526 fmFont.lInternalLeading = 0L;
1527 fmFont.lExternalLeading = 0L;
1528 fmFont.lAveCharWidth = 0L;
1529 fmFont.lMaxCharInc = 0L;
1530 fmFont.lEmInc = 1000L;
1531 fmFont.lMaxBaselineExt = 0L;
1532 fmFont.sCharSlope = 0;
1533 fmFont.sInlineDir = 0;
1534 fmFont.sCharRot = 0;
1535 fmFont.usWeightClass = FW_NORMAL;
1536 fmFont.usWidthClass = 5;
1537 fmFont.sXDeviceRes = 1000;
1538 fmFont.sYDeviceRes = 1000;
1539 fmFont.sFirstChar = FIRST_CHAR;
1540 fmFont.sLastChar = LAST_CHAR;
1541 fmFont.sDefaultChar = 31;
1542 fmFont.sBreakChar = 31;
1543 fmFont.sNominalPointSize = 120;
1544 fmFont.sMinimumPointSize = 10;
1545 fmFont.sMaximumPointSize = 7200;
1546 fmFont.fsType = 0;
1547 fmFont.fsDefn = 1;
1548 fmFont.fsSelection = 0;
1549 fmFont.fsCapabilities = 0;
1550 fmFont.lSubscriptXSize = 0L;
1551 fmFont.lSubscriptYSize = 0L;
1552 fmFont.lSubscriptXOffset = 0L;
1553 fmFont.lSubscriptYOffset = 0L;
1554 fmFont.lSuperscriptXSize = 0L;
1555 fmFont.lSuperscriptYSize = 0L;
1556 fmFont.lSuperscriptXOffset = 0L;
1557 fmFont.lSuperscriptYOffset = 0L;
1558 fmFont.lUnderscoreSize = 0L;
1559 fmFont.lUnderscorePosition = 0L;
1560 fmFont.lStrikeoutSize = 0L;
1561 fmFont.lStrikeoutPosition = 0L;
1562 fmFont.sKerningPairs = afm.cKPairs = 0;
1563 fmFont.sFamilyClass = 0;
1564 fmFont.lMatch = 0L;
1565
1566 /*
1567 ** Character metrics stuff
1568 */
1569
1570 for (i = 0; i < MAX_CHARS; afm.rgcm[i++].ipscriptCode = -1)
1571 ;
1572 fhIn = fopen( rgchIn, "r" );
1573
1574 if (fhIn == NULL )
1575 report_error(err_cantopen, rgchIn);
1576// fhOut = fopen( rgchOut, "wb" );
1577
1578// if (fhOut == NULL )
1579// report_error(err_cantcreate, rgchOut);
1580
1581 // printf("Converting %s to %s\n", rgchIn, rgchOut);
1582}
1583
1584/***************************************************************************
1585 *
1586 * FUNCTION NAME = FixCharWidths
1587 *
1588 * DESCRIPTION = Any necessary character that this font does not
1589 * support will currently have ipscriptCode == -1.
1590 * Force all of these characters to map to (and have
1591 * character metrics of) the default character,
1592 * typically a blank.
1593 *
1594 * INPUT = NONE.
1595 * OUTPUT = NONE.
1596 *
1597 * RETURN-NORMAL = NONE.
1598 * RETURN-ERROR = NONE.
1599 *
1600 ************************************************************************* */
1601
1602VOID FixCharWidths( VOID )
1603{
1604 CMData cmSpace;
1605 SHORT i;
1606
1607 cmSpace = afm.rgcm[32];
1608
1609 for (i = 0; i < MAX_CHARS; ++i)
1610
1611 if (afm.rgcm[i].ipscriptCode == -1)
1612 afm.rgcm[i] = cmSpace;
1613}
1614
1615/***************************************************************************
1616 *
1617 * FUNCTION NAME = SetAfm
1618 *
1619 * DESCRIPTION = Finish setting the character and font metrics in the
1620 * afm to their proper values.
1621 *
1622 * INPUT = NONE.
1623 * OUTPUT = NONE.
1624 *
1625 * RETURN-NORMAL = NONE.
1626 * RETURN-ERROR = NONE.
1627 *
1628 ************************************************************************* */
1629
1630VOID SetAfm( VOID )
1631{
1632 long lSumx = 0L;
1633 register SHORT i;
1634 register SHORT x;
1635
1636
1637 if (!afm.fVariablePitch)
1638 {
1639 x = afm.rgcm[fmFont.sFirstChar].cvec.x;
1640
1641 for (i = fmFont.sFirstChar; i <= (fmFont.sFirstChar+fmFont.sLastChar); ++i)
1642 afm.rgcm[i].cvec.x = x;
1643 }
1644
1645 /*
1646 ** set average width, lowercase ascent, and lowercase descent
1647 */
1648
1649 for (i = 'a'; i <= 'z'; i++)
1650 {
1651 lSumx += (long)afm.rgcm[i].cvec.x *iWeightFactor[i-'a'];
1652
1653 if (afm.rgcm[i].rc.top > fmFont.lLowerCaseAscent)
1654 fmFont.lLowerCaseAscent = afm.rgcm[i].rc.top;
1655
1656 if (abs(afm.rgcm[i].rc.bottom) > fmFont.lLowerCaseDescent)
1657 fmFont.lLowerCaseDescent = abs(afm.rgcm[i].rc.bottom);
1658 }
1659 lSumx += (long)afm.rgcm[' '].cvec.x *iWeightFactor[i-'a'];
1660 fmFont.lAveCharWidth = lSumx/1000L;
1661
1662 /*
1663 ** set maximum width
1664 */
1665
1666 for (i = fmFont.sFirstChar; i <= fmFont.sLastChar; ++i)
1667
1668 if (afm.rgcm[i].cvec.x > afm.iMaxWidth)
1669 afm.iMaxWidth = afm.rgcm[i].cvec.x;
1670
1671 /*
1672 ** If this font cannot provide winthorn multi-codepage support,
1673 ** we better change some of the fields in the font metrics.
1674 */
1675
1676 if (szIsEqual(afm.szEncodingScheme, "FontSpecific"))
1677 {
1678 fmFont.sFirstChar = 1;
1679 fmFont.sLastChar = 255;
1680 fmFont.usCodePage = ARBITRARY_CODEPAGE;
1681 }
1682
1683 /*
1684 ** Make sure the strikeout size and position are set reasonably
1685 */
1686
1687 if ((!fmFont.lStrikeoutSize) || (!fmFont.lStrikeoutPosition))
1688 {
1689 fmFont.lStrikeoutPosition = 300L;
1690
1691 if (fmFont.lUnderscoreSize)
1692 fmFont.lStrikeoutSize = fmFont.lUnderscoreSize;
1693
1694 else
1695 fmFont.lStrikeoutSize = 66L;
1696 }
1697
1698 /*
1699 ** Set the internal leading field
1700 */
1701
1702 if (fmFont.lEmHeight)
1703 fmFont.lInternalLeading = (fmFont.lMaxAscender+fmFont.lMaxDescender)-1000L;
1704}
1705
1706/***************************************************************************
1707 *
1708 * FUNCTION NAME = ResetBuffout
1709 *
1710 * DESCRIPTION = This function resets output buffer.
1711 *
1712 * INPUT = NONE.
1713 * OUTPUT = NONE.
1714 *
1715 * RETURN-NORMAL = NONE.
1716 * RETURN-ERROR = NONE.
1717 *
1718 ************************************************************************* */
1719
1720VOID ResetBuffout( VOID )
1721{
1722 pbBuffout = rgbBuffout;
1723 cbBuffout = 0;
1724}
1725
1726/***************************************************************************
1727 *
1728 * FUNCTION NAME = IncBuffout
1729 *
1730 * DESCRIPTION = These functions adjust cbBuffout by the amount indicated.
1731 * If the amount is zero, the offset is adjusted to be
1732 * word-aligned.
1733 *
1734 * INPUT = i - amount to increment
1735 *
1736 * OUTPUT = NONE.
1737 *
1738 * RETURN-NORMAL = NONE.
1739 * RETURN-ERROR = NONE.
1740 *
1741 ************************************************************************* */
1742
1743IncBuffout(SHORT i)
1744{
1745
1746 if ((!i) && (cbBuffout&1))
1747 {
1748 cbBuffout++;
1749 pbBuffout++;
1750 }
1751
1752 else
1753 {
1754 cbBuffout += i;
1755
1756 if (cbBuffout >= (SHORT)sizeof(rgbBuffout))
1757 report_error(err_overflow, NULL);
1758 }
1759 return (cbBuffout);
1760}
1761
1762/***************************************************************************
1763 *
1764 * FUNCTION NAME = PutByte
1765 *
1766 * DESCRIPTION = This function writes a byte to the output buffer.
1767 *
1768 * INPUT = iByte - byte to write
1769 *
1770 * OUTPUT = NONE.
1771 *
1772 * RETURN-NORMAL = NONE.
1773 * RETURN-ERROR = NONE.
1774 *
1775 ************************************************************************* */
1776
1777VOID PutByte( SHORT iByte)
1778{
1779 *pbBuffout++ = iByte&0x0ff;
1780 IncBuffout(1);
1781}
1782
1783/***************************************************************************
1784 *
1785 * FUNCTION NAME = PutRgb
1786 *
1787 * DESCRIPTION = This function writes an array of bytes to the output
1788 * buffer.
1789 *
1790 * INPUT = pb - array of bytes
1791 * cb - count of bytes
1792 *
1793 * OUTPUT = NONE.
1794 *
1795 * RETURN-NORMAL = NONE.
1796 * RETURN-ERROR = NONE.
1797 *
1798 ************************************************************************* */
1799
1800VOID PutRgb(char *pb,SHORT cb)
1801{
1802
1803 while (--cb >= 0)
1804 PutByte(*pb++);
1805}
1806
1807/***************************************************************************
1808 *
1809 * FUNCTION NAME = PutWord
1810 *
1811 * DESCRIPTION = These functions write a word to the output buffer.
1812 *
1813 * INPUT = iWord - word to write
1814 *
1815 * OUTPUT = NONE.
1816 *
1817 * RETURN-NORMAL = NONE.
1818 * RETURN-ERROR = NONE.
1819 *
1820 ************************************************************************* */
1821
1822VOID PutWord( SHORT iWord)
1823{
1824 *pbBuffout++ = iWord&0x0ff;
1825 *pbBuffout++ = (iWord >> 8)&0x0ff;
1826 IncBuffout(2);
1827}
1828
1829/***************************************************************************
1830 *
1831 * FUNCTION NAME = PutDword
1832 *
1833 * DESCRIPTION = These functions writes a long word to the output buffer.
1834 *
1835 * INPUT = lWord - double word to output
1836 *
1837 * OUTPUT = NONE.
1838 *
1839 * RETURN-NORMAL = NONE.
1840 * RETURN-ERROR = NONE.
1841 *
1842 ************************************************************************* */
1843
1844VOID PutDword(long lWord)
1845{
1846 PutWord((int)(lWord&0x0ffffL));
1847 lWord >>= 16;
1848 PutWord((int)(lWord&0x0ffffL));
1849}
1850
1851/***************************************************************************
1852 *
1853 * FUNCTION NAME = PutString
1854 *
1855 * DESCRIPTION = This function writes a null terminated string to the
1856 * output file.
1857 *
1858 * INPUT = psz - string to output
1859 *
1860 * OUTPUT = NONE.
1861 *
1862 * RETURN-NORMAL = NONE.
1863 * RETURN-ERROR = NONE.
1864 *
1865 ************************************************************************* */
1866
1867VOID PutString(char *psz)
1868{
1869 SHORT bCh;
1870
1871 do
1872 {
1873 bCh = *pbBuffout++ = *psz++;
1874 IncBuffout(1);
1875 }
1876
1877 while (bCh);
1878}
1879
1880/***************************************************************************
1881 *
1882 * FUNCTION NAME = FillString
1883 *
1884 * DESCRIPTION = This function writes a null terminated string to
1885 * the output file, filling the rest of the indicated
1886 * buffer with zeroes.
1887 *
1888 * INPUT = psz - string to write
1889 * iSize - total number of bytes
1890 *
1891 * OUTPUT = NONE.
1892 *
1893 * RETURN-NORMAL = NONE.
1894 * RETURN-ERROR = NONE.
1895 *
1896 ************************************************************************* */
1897
1898VOID FillString(char *psz,SHORT iSize)
1899{
1900 SHORT bCh;
1901 char *p1sz;
1902
1903 p1sz = psz; /* mark beginning */
1904
1905 while (*psz)
1906 { /* fill in the string... */
1907 *pbBuffout++ = *psz++;
1908 IncBuffout(1);
1909 }
1910 bCh = iSize-(psz-p1sz); /* ...calculate # nulls */
1911
1912 do
1913 { /* & zero the rest of the buffer */
1914 *pbBuffout++ = 0;
1915 IncBuffout(1);
1916 }
1917
1918 while (--bCh);
1919}
1920
1921/***************************************************************************
1922 *
1923 * FUNCTION NAME = WriteOutput
1924 *
1925 * DESCRIPTION = This function writes the device font info structure
1926 * to the output file.
1927 *
1928 * INPUT = pass
1929 *
1930 * OUTPUT = NONE.
1931 *
1932 * RETURN-NORMAL = NONE.
1933 * RETURN-ERROR = NONE.
1934 *
1935 ************************************************************************* */
1936
1937VOID WriteOutput( SHORT pass )
1938{
1939 char c;
1940 register SHORT i, j, count;
1941 static unsigned offGlobal;
1942 static unsigned offCharMetrics;
1943 static unsigned offPairKerning;
1944 static unsigned offStrings;
1945 static unsigned offMetrics;
1946 static unsigned sizeAll;
1947 static char outstr[] = " %-20.20s %.50s\n";
1948 static char outint[] = " %-20.20s %d\n";
1949 static char *boolstr[] =
1950 {
1951 "false","true"
1952 }
1953 ;
1954 static char outrect[] = " %-20.20s %d,%d,%d,%d\n";
1955 static char outmetric[] = " '%c' %4d,%-4d [%4d,%4d,%4d,%4d]\n";
1956
1957
1958 if (pass == 1 && fListStats)
1959 {
1960 printf("\nResults:\n");
1961 printf(outstr, tokens[tok_fontname], afm.szFontName);
1962 printf(outstr, tokens[tok_comment], afm.szComment);
1963 printf(outstr, tokens[tok_weight], afm.szWeight);
1964 printf(outint, tokens[tok_weight], fmFont.usWeightClass);
1965 printf(outint, tokens[tok_italicangle], fmFont.sCharSlope);
1966 printf(outstr, tokens[tok_isfixedpitch], boolstr[!afm.fVariablePitch]);
1967 printf(outrect, tokens[tok_fontbox], afm.rcBBox.left, afm.rcBBox.bottom,
1968 afm.rcBBox.right, afm.rcBBox.top);
1969 printf(outint, tokens[tok_underlineposition], fmFont.lUnderscorePosition);
1970 printf(outint, tokens[tok_underlinethickness], fmFont.lUnderscoreSize);
1971 printf(outint, tokens[tok_ascender], (WORD)fmFont.lMaxAscender);
1972 printf(outint, tokens[tok_descender], (WORD)fmFont.lMaxDescender);
1973 printf(outstr, tokens[tok_version], afm.szVersion);
1974 printf(outstr, tokens[tok_notice], afm.szNotice);
1975 }
1976 ResetBuffout();
1977 PutWord(afm.version);
1978 PutWord(offGlobal);
1979 PutWord(offCharMetrics);
1980 PutWord(offPairKerning);
1981 PutWord(offStrings);
1982 PutWord(offMetrics);
1983 PutWord(sizeAll);
1984
1985 /*
1986 ** write the global font info
1987 */
1988
1989 offGlobal = IncBuffout(0);
1990 PutWord(afm.fVariablePitch);
1991 PutWord(afm.rcBBox.left);
1992 PutWord(afm.rcBBox.bottom);
1993 PutWord(afm.rcBBox.right);
1994 PutWord(afm.rcBBox.top);
1995 PutWord(afm.iCapHeight);
1996
1997 /*
1998 ** character metrics
1999 */
2000
2001 offCharMetrics = IncBuffout(0);
2002
2003 for (i = fmFont.sFirstChar; i <= (fmFont.sFirstChar+fmFont.sLastChar); i++)
2004 {
2005 PutByte((BYTE)afm.rgcm[i].ipscriptCode);
2006 PutWord(afm.rgcm[i].cvec.x);
2007
2008 if (pass == 1 && fListMetrics)
2009 {
2010
2011 if (i == fmFont.sFirstChar)
2012 printf("\nMetrics:\n");
2013 c = i;
2014
2015 if (!isprint(c))
2016 c = ' ';
2017 printf(outmetric, c, afm.rgcm[i].cvec.x, afm.rgcm[i].cvec.y, afm.rgcm[i].
2018 rc.left, afm.rgcm[i].rc.bottom, afm.rgcm[i].rc.right, afm.rgcm[i].
2019 rc.top);
2020 }
2021 }
2022
2023 /*
2024 ** pair kerning data
2025 */
2026
2027 offPairKerning = IncBuffout(0);
2028
2029 i = 0;
2030 while ( i < afm.cKPairs )
2031 {
2032 /* Count num pairs with same key1 */
2033 count = 0;
2034 for (j = i; afm.rgKPairs[i].iKey1 == afm.rgKPairs[j].iKey1; j++ )
2035 {
2036 count++;
2037 }
2038
2039 PutByte((BYTE)(afm.rgKPairs[i].iKey1));
2040 PutByte( (BYTE)count );
2041
2042 for ( j = 0; j < count; j++, i++ )
2043 {
2044 PutByte((BYTE)(afm.rgKPairs[i].iKey2));
2045 PutWord(afm.rgKPairs[i].sAmount);
2046 }
2047 }
2048
2049 /*
2050 ** strings
2051 */
2052
2053 offStrings = IncBuffout(0);
2054 PutString(afm.szFontName);
2055/*PutString(afm.szComment); LMT */
2056/*PutString(afm.szVersion); LMT */
2057/*PutString(afm.szNotice); LMT */
2058/*PutString(afm.szEncodingScheme); LMT */
2059/*PutString(afm.szWeight); LMT */
2060
2061 /*
2062 ** font metrics
2063 */
2064
2065 offMetrics = IncBuffout(0);
2066 FillString(fmFont.szFamilyname, FACESIZE);
2067 FillString(fmFont.szFacename, FACESIZE);
2068 PutWord(fmFont.idRegistry);
2069 PutWord(fmFont.usCodePage);
2070 PutDword(fmFont.lEmHeight);
2071 PutDword(fmFont.lXHeight);
2072 PutDword(fmFont.lMaxAscender);
2073 PutDword(fmFont.lMaxDescender);
2074 PutDword(fmFont.lLowerCaseAscent);
2075 PutDword(fmFont.lLowerCaseDescent);
2076 PutDword(fmFont.lInternalLeading);
2077 PutDword(fmFont.lExternalLeading);
2078 PutDword(fmFont.lAveCharWidth);
2079 PutDword(fmFont.lMaxCharInc);
2080 PutDword(fmFont.lEmInc);
2081 PutDword(fmFont.lMaxAscender+fmFont.lMaxDescender);
2082 PutWord(fmFont.sCharSlope);
2083 PutWord(fmFont.sInlineDir);
2084 PutWord(fmFont.sCharRot);
2085 PutWord(fmFont.usWeightClass);
2086 PutWord(fmFont.usWidthClass);
2087 PutWord(fmFont.sXDeviceRes);
2088 PutWord(fmFont.sYDeviceRes);
2089 PutWord(fmFont.sFirstChar);
2090 PutWord(fmFont.sLastChar);
2091 PutWord(fmFont.sDefaultChar);
2092 PutWord(fmFont.sBreakChar);
2093 PutWord(fmFont.sNominalPointSize);
2094 PutWord(fmFont.sMinimumPointSize);
2095 PutWord(fmFont.sMaximumPointSize);
2096 PutWord(fmFont.fsType);
2097 PutWord(fmFont.fsDefn);
2098 PutWord(fmFont.fsSelection);
2099 PutWord(fmFont.fsCapabilities);
2100 PutDword(fmFont.lSubscriptXSize);
2101 PutDword(fmFont.lSubscriptYSize);
2102 PutDword(fmFont.lSubscriptXOffset);
2103 PutDword(fmFont.lSubscriptYOffset);
2104 PutDword(fmFont.lSuperscriptXSize);
2105 PutDword(fmFont.lSuperscriptYSize);
2106 PutDword(fmFont.lSuperscriptXOffset);
2107 PutDword(fmFont.lSuperscriptYOffset);
2108 PutDword(fmFont.lUnderscoreSize);
2109 PutDword(fmFont.lUnderscorePosition);
2110 PutDword(fmFont.lStrikeoutSize);
2111 PutDword(fmFont.lStrikeoutPosition);
2112 PutWord(fmFont.sKerningPairs);
2113 PutWord(fmFont.sFamilyClass);
2114 PutDword(fmFont.lMatch);
2115
2116 /*
2117 ** total size
2118 */
2119
2120 sizeAll = IncBuffout(0)-offGlobal;
2121
2122 if (pass == 1)
2123 WriteOutput(2);
2124
2125 else
2126 {
2127
2128 if (cbBuffout && fhOut)
2129 fwrite(rgbBuffout, 1, cbBuffout, fhOut);
2130 }
2131}
2132
2133/***************************************************************************
2134 *
2135 * FUNCTION NAME = AddExtension
2136 *
2137 * DESCRIPTION = If given filename has no extension, add the given default.
2138 *
2139 * INPUT = pszName - filename
2140 * pszDefext - default filename extension
2141 *
2142 * OUTPUT = NONE.
2143 *
2144 * RETURN-NORMAL = NONE.
2145 * RETURN-ERROR = NONE.
2146 *
2147 ************************************************************************* */
2148
2149VOID AddExtension(char *pszName,char *pszDefext)
2150{
2151 char c;
2152 SHORT l;
2153 register char *p;
2154
2155 l = strlen(pszName);
2156 p = pszName+l;
2157 c = '.';
2158
2159 while (l-- > 0)
2160 {
2161 c = *--p;
2162
2163 if (c == '.' || c == '\\' || c == ':')
2164 break;
2165 }
2166
2167 if (c != '.')
2168 strcat(p, pszDefext);
2169}
2170
2171/***************************************************************************
2172 *
2173 * FUNCTION NAME = RemoveExtension
2174 *
2175 * DESCRIPTION = Removes any extension from the given filename.
2176 *
2177 * INPUT = pszName - filename
2178 *
2179 * OUTPUT = NONE.
2180 *
2181 * RETURN-NORMAL = NONE.
2182 * RETURN-ERROR = NONE.
2183 *
2184 ************************************************************************* */
2185
2186VOID RemoveExtension(char *pszName)
2187{
2188 char c;
2189 SHORT l;
2190 register char *p;
2191
2192 l = strlen(pszName);
2193 p = pszName+l;
2194 c = '.';
2195
2196 while (l-- > 0)
2197 {
2198 c = *--p;
2199
2200 if (c == '.' || c == '\\' || c == ':')
2201 break;
2202 }
2203
2204 if (c == '.')
2205 *p = 0;
2206}
2207
2208
2209#if 0
2210/***************************************************************************
2211 *
2212 * FUNCTION NAME = GetArgs
2213 *
2214 * DESCRIPTION = Parses all args passed to the program.
2215 *
2216 * INPUT = argc - argument count
2217 * argv - array of pointers to arguments
2218 *
2219 * OUTPUT = NONE.
2220 *
2221 * RETURN-NORMAL = NONE.
2222 * RETURN-ERROR = NONE.
2223 *
2224 ************************************************************************* */
2225
2226VOID GetArgs(SHORT argc,char **argv)
2227{
2228 BOOL argerror = FALSE;
2229 register char c,*p;
2230
2231 report_warning(err_ver, NULL);
2232
2233 if (argc <= 1)
2234 argerror = TRUE;
2235
2236 while (--argc)
2237 {
2238 p = *++argv;
2239
2240 if (*p == '-' || *p == '/')
2241 {
2242
2243 while (c = tolower( *++p ))
2244 {
2245
2246 switch (c)
2247 {
2248 case 'e' :
2249 fEcho = TRUE;
2250 break;
2251 case 's' :
2252 fListStats = TRUE;
2253 break;
2254 case 'm' :
2255 fListMetrics = TRUE;
2256 break;
2257 case 'v' :
2258 fListStats = TRUE;
2259 fListMetrics = TRUE;
2260 break;
2261
2262
2263 // Add conditional for displaying warnings.
2264 case 'w':
2265 FReportWarning = TRUE;
2266 break;
2267
2268 default :
2269 argerror = TRUE;
2270 report_warning(err_option, p);
2271 break;
2272 }
2273 }
2274 }
2275
2276 else
2277 {
2278
2279 if (!rgchIn[0])
2280 {
2281 szMove(rgchIn, p, sizeof(rgchIn));
2282 AddExtension(rgchIn, DEF_IEXT);
2283 }
2284
2285 else
2286
2287 if (!rgchOut[0])
2288 {
2289 szMove(rgchOut, p, sizeof(rgchOut));
2290 AddExtension(rgchOut, DEF_OEXT);
2291 }
2292
2293 else
2294 {
2295 argerror = TRUE;
2296 report_warning(err_arg, p);
2297 }
2298 }
2299 }
2300
2301 if (rgchIn[0] && !rgchOut[0])
2302 {
2303 szMove(rgchOut, rgchIn, sizeof(rgchIn));
2304 RemoveExtension(rgchOut);
2305 AddExtension(rgchOut, DEF_OEXT);
2306 }
2307 strlwr(rgchIn);
2308 strlwr(rgchOut);
2309
2310 if (rgchIn[0])
2311
2312 if (szIsEqual(rgchIn, rgchOut))
2313 {
2314 argerror = TRUE;
2315 report_warning(err_badoutput, NULL);
2316 }
2317
2318 if (argerror)
2319 report_error(err_usage, NULL);
2320}
2321#endif
2322
2323
2324/***************************************************************************
2325 *
2326 * FUNCTION NAME = GetNextWord
2327 *
2328 * DESCRIPTION = This routine copies the next word delimited by
2329 * white space from the source buffer to the
2330 * destination buffer and NULL terminates it. It
2331 * returns a pointer to the end position of the word
2332 * in the source buffer.
2333 *
2334 * INPUT = pszSrcStr - pointer to source area
2335 * pszDestStr - pointer to desitnation area
2336 *
2337 * OUTPUT = NONE.
2338 *
2339 * RETURN-NORMAL = NONE.
2340 * RETURN-ERROR = NONE.
2341 *
2342 ************************************************************************* */
2343
2344char *GetNextWord(char *pszSrcStr,char *pszDestStr)
2345{
2346
2347 while (*pszSrcStr && (*pszSrcStr == ' ' || *pszSrcStr == '\t'))
2348 ++pszSrcStr; /* chew any leading white space */
2349
2350 while (*pszSrcStr && (*pszSrcStr != ' ' && *pszSrcStr != '\t'))
2351 *pszDestStr++ = *pszSrcStr++;
2352 *pszDestStr = 0; /* drop NULL at end of destination */
2353 return (pszSrcStr);
2354}
2355
2356/***************************************************************************
2357 *
2358 * FUNCTION NAME = StrCopy
2359 *
2360 * DESCRIPTION = Copy finite or NULL terminated string to
2361 * destination buffer and lower case it during copy.
2362 *
2363 * INPUT = psStr - pointer to source string
2364 * pdStr - pointer to destination string
2365 * iCount - source string length
2366 *
2367 * OUTPUT = NONE.
2368 *
2369 * RETURN-NORMAL = NONE.
2370 * RETURN-ERROR = NONE.
2371 *
2372 ************************************************************************* */
2373
2374VOID StrCopy(char *psStr,char *pdStr,SHORT iCount)
2375{
2376 char c;
2377 SHORT i;
2378
2379
2380 for (i = 0; i < iCount; i++)
2381 { /* stay within finite bounds */
2382
2383 if (!(c = *psStr))
2384 break; /* pick up copy and abort if NULL */
2385
2386 if (c >= 'A' && c <= 'Z')
2387 {
2388 c += 'a'-'A';
2389 }
2390 *pdStr = c;
2391 psStr++;
2392 pdStr++;
2393 }
2394 *pdStr = 0; /* drop NULL at end of destination */
2395}
2396
2397/***************************************************************************
2398 *
2399 * FUNCTION NAME = ParseItalic
2400 *
2401 * DESCRIPTION = Parse the input string for the 'italic' key-word to
2402 * be able to set the Italic bit in the font metrics
2403 *
2404 * INPUT = NONE.
2405 * OUTPUT = NONE.
2406 *
2407 * RETURN-NORMAL = NONE.
2408 * RETURN-ERROR = NONE.
2409 *
2410 ************************************************************************* */
2411
2412VOID ParseItalic( VOID )
2413{
2414 char szStrBuff[MAX_STR];
2415 char szWrdBuff[MAX_STR];
2416 char *pszSrcStr;
2417
2418 /*
2419 ** pick up private copy of name
2420 */
2421
2422 StrCopy(afm.szFontName, szStrBuff, sizeof(afm.szFontName));
2423 pszSrcStr = szStrBuff;
2424
2425 /*
2426 ** while not at end of name string, grab the
2427 ** next word and see if it is 'italic'
2428 */
2429
2430 while (*pszSrcStr)
2431 {
2432 pszSrcStr = GetNextWord(pszSrcStr, szWrdBuff);
2433
2434 if (szIsEqual(szWrdBuff, "italic"))
2435 {
2436 fmFont.fsSelection |= FATTR_SEL_ITALIC;
2437 break;
2438 }
2439 }
2440}
2441
2442/***************************************************************************
2443 *
2444 * FUNCTION NAME = ParseFamilyClass
2445 *
2446 * DESCRIPTION = Parse the input string for the various family names
2447 * to be able to set the Family Name ID in the font
2448 * metrics
2449 *
2450 * INPUT = NONE.
2451 * OUTPUT = NONE.
2452 *
2453 * RETURN-NORMAL = NONE.
2454 * RETURN-ERROR = NONE.
2455 *
2456 ************************************************************************* */
2457
2458VOID ParseFamilyClass( VOID )
2459{
2460 char szStrBuff[MAX_STR];
2461 char szWrdBuff[MAX_STR];
2462 char *pszSrcStr;
2463
2464 /*
2465 ** pick up private copy of name
2466 */
2467
2468 StrCopy(fmFont.szFamilyname, szStrBuff, sizeof(fmFont.szFamilyname));
2469 pszSrcStr = szStrBuff;
2470
2471 /*
2472 ** while not at end of name string, grab the
2473 ** next word and run thro the various
2474 ** possibiliteis
2475 */
2476
2477 while (*pszSrcStr)
2478 {
2479 pszSrcStr = GetNextWord(pszSrcStr, szWrdBuff);
2480
2481 if ((szIsEqual(szWrdBuff, "avant")) || (szIsEqual(szWrdBuff, "helvetica")))
2482 {
2483 fmFont.sFamilyClass |= FATTR_FAM_SANS_SERIF;
2484 break;
2485 }
2486
2487 if ((szIsEqual(szWrdBuff, "bookman")) || (szIsEqual(szWrdBuff, "times")))
2488 {
2489 fmFont.sFamilyClass |= FATTR_FAM_TRANSITIONAL_SERIF;
2490 break;
2491 }
2492
2493 if ((szIsEqual(szWrdBuff, "courier")) || (szIsEqual(szWrdBuff, "lubalin")))
2494 {
2495 fmFont.sFamilyClass |= FATTR_FAM_SLAB_SERIF;
2496 break;
2497 }
2498
2499 if ((szIsEqual(szWrdBuff, "garamond")) || (szIsEqual(szWrdBuff, "palatino")
2500 ))
2501 {
2502 fmFont.sFamilyClass |= FATTR_FAM_OLD_STYLE_SERIF;
2503 break;
2504 }
2505
2506 if ((szIsEqual(szWrdBuff, "century")) || (szIsEqual(szWrdBuff, "korinna")))
2507 {
2508 fmFont.sFamilyClass |= FATTR_FAM_CLARENDON_SERIF;
2509 break;
2510 }
2511
2512 if ((szIsEqual(szWrdBuff, "souvenir")))
2513 {
2514 fmFont.sFamilyClass |= FATTR_FAM_FREEFORM_SERIF;
2515 break;
2516 }
2517
2518 if ((szIsEqual(szWrdBuff, "chancery")))
2519 {
2520 fmFont.sFamilyClass |= FATTR_FAM_SCRIPT;
2521 break;
2522 }
2523
2524 if ((szIsEqual(szWrdBuff, "symbol")) || (szIsEqual(szWrdBuff, "dingbats")))
2525 {
2526 fmFont.sFamilyClass |= FATTR_FAM_SYMBOLIC;
2527 break;
2528 }
2529 }
2530}
2531
2532
2533/* DBCS enabling start */ //@DBCS
2534/***************************************************************************
2535 *
2536 * FUNCTION NAME = ParseBaseFont
2537 *
2538 * DESCRIPTION = Parse the Base font and set the base font flag
2539 * in the fontmetrics structure.
2540 *
2541 * INPUT = NONE.
2542 * OUTPUT = NONE.
2543 *
2544 * RETURN-NORMAL = NONE.
2545 * RETURN-ERROR = NONE.
2546 *
2547 ************************************************************************* */
2548
2549VOID ParseBaseFont( VOID )
2550{
2551 char szWord[16];
2552
2553 EatWhite();
2554 GetWord(szWord, sizeof(szWord));
2555
2556 if (szIsEqual("true", szWord))
2557 {
2558 /*
2559 ** If the IsBaseFont is true, the font is for mixed
2560 ** single/double-byte code page
2561 */
2562 fmFont.fsType |= FM_TYPE_MBCS;
2563 }
2564
2565 else
2566 {
2567 fmFont.fsType &= ~FM_TYPE_MBCS;
2568 }
2569}
2570/* DBCS enabling end */ //@DBCS
2571
2572
2573
2574int Conv_AFM_Init()
2575{
2576 return 1;
2577}
2578
2579
2580int Conv_AFM_WritePFM(PSZ pszInFile, FILE *fhOutArg, PSZ pszFontName, PSZ pszFontFullName)
2581{
2582 SHORT iToken;
2583 BOOL fEndOfInput = FALSE;
2584
2585 printf(".");
2586 // clear out our previous memory (here the bugs lie... will need to track
2587 // all of those globals that need cleaning)
2588 cInline = 0;
2589 memset( &afm,0,sizeof(afm) );
2590 memset( &fmFont,0,sizeof(fmFont) );
2591 charmap = charmapAdobeStandard;
2592
2593
2594// GetArgs(argc, argv);
2595 // check parameters
2596 if(pszInFile == NULL ||
2597 fhOutArg == NULL ||
2598 pszFontName == NULL)
2599 {
2600 return FALSE; // fail if not good
2601 }
2602
2603 szMove(rgchIn,(char*)pszInFile,MAX_FNAMESIZE);
2604
2605 printf(".");
2606
2607 OpenAfm();
2608
2609 fhOut = fhOutArg;
2610
2611 printf(".");
2612
2613 while (!fEndOfInput)
2614 {
2615 GetLine();
2616 iToken = GetToken();
2617
2618 switch (iToken)
2619 {
2620 case tok_fontname :
2621 ParseString((char*)pszFontName, 40);
2622 break;
2623
2624 case tok_fullname :
2625 ParseString(afm.szFontName, sizeof(afm.szFontName));
2626 szMove(fmFont.szFacename, afm.szFontName, sizeof(fmFont.szFacename));
2627 szMove((char*)pszFontFullName,afm.szFontName,40);
2628 ParseItalic();
2629 break;
2630 case tok_familyname :
2631 ParseString(fmFont.szFamilyname, sizeof(fmFont.szFamilyname));
2632 ParseFamilyClass();
2633 break;
2634 case tok_encodingscheme :
2635 ParseString(afm.szEncodingScheme, sizeof(afm.szEncodingScheme));
2636
2637 if (szIsEqual(afm.szEncodingScheme, "FontSpecific"))
2638 charmap = charmapFontSpecific;
2639
2640 else
2641 charmap = charmapAdobeStandard;
2642 break;
2643 case tok_comment :
2644
2645 if (!afm.szComment[0])
2646 ParseString(afm.szComment, sizeof(afm.szComment));
2647 break;
2648 case tok_weight :
2649 ParseWeight();
2650 break;
2651 case tok_italicangle :
2652 fmFont.sCharSlope = GetFloat(10);
2653 break;
2654 case tok_isfixedpitch :
2655 ParsePitchType();
2656 break;
2657 case tok_fontbox :
2658 ParseBoundingBox();
2659 break;
2660 case tok_underlineposition :
2661 fmFont.lUnderscorePosition = (LONG)abs(GetNumber());
2662 break;
2663 case tok_underlinethickness :
2664 fmFont.lUnderscoreSize = (LONG)GetNumber();
2665 break;
2666/* case tok_version :
2667 ParseString(afm.szVersion, sizeof(afm.szVersion));
2668 break; */
2669/***case tok_notice :
2670 ParseString(afm.szNotice, sizeof(afm.szNotice));
2671 break; **/
2672 case tok_capheight :
2673 afm.iCapHeight = GetNumber();
2674 break;
2675 case tok_xheight :
2676 fmFont.lXHeight = (LONG)abs(GetNumber());
2677 break;
2678 case tok_ascender :
2679 (void)GetNumber();
2680 break;
2681 case tok_descender :
2682 (void)GetNumber();
2683 break;
2684 case tok_startcharmetrics :
2685 ParseCharMetrics();
2686 break;
2687 case tok_startkerndata :
2688 ParseKernData();
2689 break;
2690 case tok_startfontmetrics :
2691 afm.version = GetFloat(10);
2692 afm.version = (afm.version%10)+((afm.version/10) << 8);
2693 break;
2694 case tok_endfontmetrics :
2695 fEndOfInput = TRUE;
2696 break;
2697 case tok_isbasefont : //@DBCS
2698 ParseBaseFont(); //@DBCS
2699 break; //@DBCS
2700 }
2701 pszLine = rgbLine;
2702
2703 if (fEcho)
2704 PrintLine();
2705 }
2706
2707 printf(".");
2708
2709 fclose(fhIn);
2710 FixCharWidths();
2711 SetAfm();
2712
2713 printf(".");
2714
2715 WriteOutput(1);
2716
2717// fclose(fhOut);
2718
2719 return TRUE;
2720}
2721
2722void Conv_AFM_Done()
2723{
2724 // imagine a clean up
2725 return;
2726}
Note: See TracBrowser for help on using the repository browser.