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

Last change on this file since 2 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.