home *** CD-ROM | disk | FTP | other *** search
- #define KERNING_AVAILABLE 0x0268
- #define X_WIDTHS_AVAILABLE 0x0068
- #define AMIGA_STANDARD 0x0101
- #define FONT_SPECIFIC 0x0100
-
- ULONG WriteMetricsVector(char *afmFilename, int typeWeight)
-
- /* This function is the heart of ConvertAFM. It creates what I
- call a "Metrics Vector"; a complete .metric structure with all
- typeface information, character widths, and kerning tables.
-
- It creates a file in T: named by the AFM's typeface name.
- It contains the complete metrics vector except for the
- typeface style, which you must supply in typeWeight. It
- also returns the length of the file. */
-
- {
- static WORD kerningTables[256][256];
- static char kerningCheckList[16384];
- static char currentList[256],*kerningArray,*incomingString,headerCheck[26],encodingScheme[20],intString[4][20],metricFilename[26],typefaceName[68],*intChars;
- static WORD metricInfo[18],xWidths[256],kerningPointers[256];
- static FILE *afmFile,*metricFile;
- static int test,test2,test3,test4,test5,asciiCode,asciiCode2,xWidth,kerningArrayLength,currentOffset;
- static ULONG vectorLength;
- static UWORD index,index2;
- static BOOL goodfit;
-
- for (index=0;index<18;index++)
- metricInfo[index]=0;
- for(index=0;index<68;index++)
- typefaceName[index]=0;
- metricInfo[0]=X_WIDTHS_AVAILABLE;
- for (index=0;index<256;index++)
- xWidths[index]=0;
-
- afmFile=fopen(afmFilename,"r");
-
- if (afmFile==0)
- {
- fclose(afmFile);
- return(0);
- }
-
- /* If the AFM file didn't exist, it returns a vectorLength
- of zero. Logical, yes? A non-existant file with zero length? */
-
- headerCheck[0]=0;
- test=-1;
- while(test!=0)
- {
- incomingString=freadline(afmFile);
- sscanf(incomingString,"%s\n",headerCheck);
- test=strcmp(headerCheck,"FontName");
- }
- sscanf(incomingString,"%s %s",headerCheck,typefaceName);
-
- test=-1;
- while(test!=0)
- {
- incomingString=freadline(afmFile);
- sscanf(incomingString,"%s ",headerCheck);
- test=strcmp(headerCheck,"EncodingScheme");
- }
- sscanf(incomingString,"%s %s",headerCheck,encodingScheme);
- test=strcmp(encodingScheme,"FontSpecific");
- test2=strcmp(encodingScheme,"AppleStandard");
- if (test==0 || test2==0)
- metricInfo[6]=FONT_SPECIFIC;
- else
- metricInfo[6]=AMIGA_STANDARD;
- fsetpos(afmFile,0);
-
- /* I gotta do this for every parameter I require! Ugh! */
-
- test=-1;
- while(test!=0)
- {
- incomingString=freadline(afmFile);
- sscanf(incomingString,"%s ",headerCheck);
- test=strcmp(headerCheck,"UnderlinePosition");
- }
- sscanf(incomingString,"%s %s",headerCheck,intString[0]);
- metricInfo[11]=atoi(intString[0]);
-
- test=-1;
- while(test!=0)
- {
- incomingString=freadline(afmFile);
- sscanf(incomingString,"%s ",headerCheck);
- test=strcmp(headerCheck,"UnderlineThickness");
- }
- sscanf(incomingString,"%s %s",headerCheck,intString[0]);
- metricInfo[12]=atoi(intString[0]);
-
- test=-1;
- while(test!=0)
- {
- incomingString=freadline(afmFile);
- sscanf(incomingString,"%s ",headerCheck);
- test=strcmp(headerCheck,"FontBBox");
- }
- sscanf(incomingString,"%s %s %s %s %s",headerCheck,intString[0],intString[1],intString[2],intString[3]);
- for (index=0;index<4;index++)
- metricInfo[index+7]=atoi(intString[index]);
-
- /* Some typefaces won't have letter-like qualities, like
- cap height, x-height, etc. So, if the very next line is
- "StartCharMetrics", then it creates these values based
- on the Font Bounding Box. */
-
- test=-1;
- incomingString=freadline(afmFile);
- sscanf(incomingString,"%s ",headerCheck);
- test=strcmp(headerCheck,"StartCharMetrics");
-
- if (test!=0)
- {
- test2=-1;
- while(test2!=0)
- {
- sscanf(incomingString,"%s ",headerCheck);
- test2=strcmp(headerCheck,"CapHeight");
- }
- sscanf(incomingString,"%s %s",headerCheck,intString[0]);
- metricInfo[13]=atoi(intString[0]);
-
- test2=-1;
- while(test2==0)
- {
- incomingString=freadline(afmFile);
- sscanf(incomingString,"%s ",headerCheck);
- test2=strcmp(headerCheck,"XHeight");
- }
- sscanf(incomingString,"%s %s",headerCheck,intString[0]);
- metricInfo[14]=atoi(intString[0]);
-
- test2=-1;
- while(test2!=0)
- {
- incomingString=freadline(afmFile);
- sscanf(incomingString,"%s ",headerCheck);
- test2=strcmp(headerCheck,"Descender");
- }
- sscanf(incomingString,"%s %s",headerCheck,intString[0]);
- metricInfo[16]=atoi(intString[0]);
-
- test2=-1;
- while(test2!=0)
- {
- incomingString=freadline(afmFile);
- sscanf(incomingString,"%s ",headerCheck);
- test2=strcmp(headerCheck,"Ascender");
- }
- sscanf(incomingString,"%s %s",headerCheck,intString[0]);
- metricInfo[15]=atoi(intString[0]);
-
- incomingString=freadline(afmFile);
- sscanf(incomingString,"%s %s",headerCheck,intString[0]);
-
- }
- else
- {
- for (index=13;index<17;index++)
- metricInfo[index]=0;
- sscanf(incomingString,"%s %s",headerCheck,intString[0]);
- metricInfo[16]=metricInfo[8];
- for (index=13;index<16;index++)
- metricInfo[index]=metricInfo[8]+metricInfo[10];
- }
-
- metricInfo[17]=typeWeight;
-
- /* By now we're on the very first line of x-widths.
- We start by comparing all the chars to either Amiga Standard
- or Apple Standard encoding and arrange the X-widths in an
- ASCII format. The check arrays #included are used for this.
- If the typeface has Font Specific encoding the ASCII values
- are used directly. */
-
- vectorLength=104;
- if (metricInfo[6]==FONT_SPECIFIC)
- {
- test2=-1;
- incomingString=freadline(afmFile);
- while (test2!=0)
- {
- sscanf(incomingString,"C %s ; WX %s ",intString[0],intString[1]);
- asciiCode=atoi(intString[0]);
- if (asciiCode!=-1)
- xWidths[asciiCode]=atoi(intString[1]);
-
- incomingString=freadline(afmFile);
- test2=strcmp(incomingString,"EndCharMetrics");
- }
- vectorLength=vectorLength+256*2;
- }
- else
- {
- test2=-1;
- incomingString=freadline(afmFile);
- while (test2!=0)
- {
- sscanf(incomingString,"C %s ; WX %s ; N %s ",intString[0],intString[1],intString[2]);
- index=0;asciiCode=-1;
- while (asciiCode==-1 && index<256)
- {
- test=strcmp(amigaEncoding[index],intString[2]);
- if (test==0)
- asciiCode=index;
- else
- index=index+1;
- }
- if (asciiCode!=-1)
- xWidths[asciiCode]=atoi(intString[1]);
-
- incomingString=freadline(afmFile);
- test2=strcmp(incomingString,"EndCharMetrics");
- }
- vectorLength=vectorLength+256*2;
- }
-
- /* If this is any type of standard encoding, I look for kerning
- tables. This means AdobeStandard, AppleStandard, or whatever.
-
- NOTE: Font Specific encoded typefaces CANNOT have kerning
- tables or this program will ignore them. To add kerning to
- a font specific encoded typeface, you'll have to wait for
- my kerning pair editor to be released.
-
- Anyway, on to kerning pair decyphering. */
-
- test=-1;test2=-1;
- while (test!=0 && test2!=0)
- {
- incomingString=freadline(afmFile);
- test=strcmp(incomingString,"StartKernData");
- test2=strcmp(incomingString,"EndFontMetrics");
- }
- test2=strcmp(encodingScheme,"FontSpecific");
- if (test==0 && test2!=0)
- {
-
- for (index=0;index<256;index++)
- for (index2=0;index2<256;index2++)
- kerningTables[index][index2]=0;
-
- test3=-1;
- while (test3!=0)
- {
- incomingString=freadline(afmFile);
- sscanf(incomingString,"%s ",headerCheck);
- test3=strcmp(headerCheck,"StartKernPairs");
- }
- test3=-1;
- incomingString=freadline(afmFile);
- test=strcmp(incomingString,"EndKernPairs");
- while (test3!=0)
- {
- sscanf(incomingString,"%s ",headerCheck);
- test4=strcmp(headerCheck,"KPX");
- if (test4==0)
- {
- sscanf(incomingString,"KPX %s %s %s",intString[0],intString[1],intString[2]);
- index=0;asciiCode=-1;
- while (asciiCode==-1 && index<256)
- {
- test5=strcmp(amigaEncoding[index],intString[0]);
- if (test5==0)
- asciiCode=index;
- else
- index=index+1;
- }
- index=0;asciiCode2=-1;
- while (asciiCode2==-1 && index<256)
- {
- test5=strcmp(amigaEncoding[index],intString[1]);
- if (test5==0)
- asciiCode2=index;
- else
- index=index+1;
- }
- kerningTables[asciiCode][asciiCode2]=atoi(intString[2]);
- }
- incomingString=freadline(afmFile);
- test3=strcmp(incomingString,"EndKernPairs");
- }
- for (index=0;index<256;index++)
- for (index2=0;index2<256;index2++)
- if (kerningTables[index][index2]!=0)
- {
- kerningPointers[index]=256;
- index2=256;
- }
- else
- kerningPointers[index]=0;
-
- /* Since making a separate function for encoding the kerning
- array doesn't work with DICE (UGH!) I have to include it
- here. */
-
- for (index=0;index<16384;index++)
- kerningCheckList[index]=32;
- /* kerningCheckList nulled to spaces. */
-
- kerningArrayLength=256;
-
- for (index=0;index<256;index++)
- {
- if (kerningPointers[index]!=0)
- {
- for (index2=0;index2<256;index2++)
- {
- if (kerningTables[index][index2]!=0)
- currentList[index2]=index;
- else
- currentList[index2]=32;
- }
- /* CurrentList created. */
- goodfit=TRUE;currentOffset=0;
- for (index2=0;index2<256;index2++)
- {
- if (currentList[index2]!=32 && kerningCheckList[index2]!=32)
- {
- goodfit=FALSE;
- index2=256;
- }
- }
- while (goodfit==FALSE)
- {
- currentOffset=currentOffset+1;
- for (index2=0;index2<256;index2++)
- {
- if (currentList[index2]!=32 && kerningCheckList[index2+currentOffset]!=32)
- {
- goodfit=FALSE;
- index2=256;
- }
- else
- goodfit=TRUE;
- }
- }
-
- /* A good fit was found. Record the offset and insert
- into the check array. */
-
- for (index2=0;index2<256;index2++)
- if (currentList[index2]!=32)
- kerningCheckList[index2+currentOffset]=currentList[index2];
-
- kerningPointers[index]=kerningPointers[index]+currentOffset;
- if (kerningArrayLength < currentOffset+256)
- kerningArrayLength=kerningArrayLength+(currentOffset+256-kerningArrayLength);
- }
- /* NEXT! */
- }
- for (index=0;index<256;index++)
- if (kerningPointers[index]!=0)
- {
- vectorLength=vectorLength+256*4+kerningArrayLength*4;
- metricInfo[2]=KERNING_AVAILABLE;
- index=256;
- }
-
- }
-
- fclose(afmFile);
-
- strcpy(metricFilename,"T:");
- strcat(metricFilename,typefaceName);
- metricFile=fopen(metricFilename,"w");
-
- for (index=0;index<68;index++)
- fputc(typefaceName[index],metricFile);
-
- for (index=0;index<18;index++)
- {
- intChars=&metricInfo[index];
- fprintf(metricFile,"%c%c",intChars[0],intChars[1]);
- }
-
- for (index=0;index<256;index++)
- {
- intChars=&xWidths[index];
- fprintf(metricFile,"%c%c",intChars[0],intChars[1]);
- }
-
- if (metricInfo[2]==KERNING_AVAILABLE)
- {
- for (index=0;index<256;index++)
- if (kerningPointers[index]!=0)
- {
- intChars=&kerningPointers[index];
- fprintf(metricFile,"%c%c%c%c",intChars[0],intChars[1],0,index);
- }
- else
- fprintf(metricFile,"%c%c%c%c",0,0,0,0);
-
- for (index=0;index<kerningArrayLength;index++)
- if (kerningCheckList[index]!=32)
- {
- asciiCode=kerningCheckList[index];
- asciiCode2=index-kerningPointers[asciiCode]+256;
- intChars=&kerningTables[asciiCode][asciiCode2];
- fprintf(metricFile,"%c%c%c%c",intChars[0],intChars[1],0,asciiCode);
- }
- else
- fprintf(metricFile,"%c%c%c%c",0,0,0,0);
-
- /* Cheaky way of writing the kerning table, eh? :-) */
-
- }
-
- fclose(metricFile);
- return(vectorLength);
-
- };
-