- // Julian - we'll need to do this a different way now we've removed the
- // font directory system. Must find Stefan's original code.
-
- name = wxTheFontNameDirectory->GetAFMName(Family, Weight, Style);
- if (!name)
- name = "unknown";
-
- // get the directory of the AFM files
- char afmName[256];
- afmName[0] = 0;
- if (wxGetAFMPath())
- strcpy(afmName,wxGetAFMPath());
-
- // 2. open and process the file **********************************
-
- // a short explanation of the AFM format:
- // we have for each character a line, which gives its size
- // e.g.:
- //
- // C 63 ; WX 444 ; N question ; B 49 -14 395 676 ;
- //
- // that means, we have a character with ascii code 63, and width
- // (444/1000 * fontSize) points.
- // the other data is ignored for now!
- //
- // when the font has changed, we read in the right AFM file and store the
- // character widths in an array, which is processed below (see point 3.).
-
- // new elements JC Sun Aug 25 23:21:44 MET DST 1996
-
-
- strcat(afmName,name);
- strcat(afmName,".afm");
- FILE *afmFile = fopen(afmName,"r");
- if(afmFile==NULL){
- wxLogDebug("GetTextExtent: can't open AFM file '%s'\n",afmName);
- wxLogDebug(" using approximate values\n");
- int i;
- for (i=0; i<256; i++) lastWidths[i] = 500; // an approximate value
- lastDescender = -150; // dito.
- }else{
- int i;
- // init the widths array
- for(i=0; i<256; i++) lastWidths[i]= INT_MIN;
- // some variables for holding parts of a line
- char cString[10],semiString[10],WXString[10],descString[20];
- char upString[30], utString[30], encString[50];
- char line[256];
- int ascii,cWidth;
- // read in the file and parse it
- while(fgets(line,sizeof(line),afmFile)!=NULL){
- // A.) check for descender definition
- if(strncmp(line,"Descender",9)==0){
- if((sscanf(line,"%s%d",descString,&lastDescender)!=2)
- || (strcmp(descString,"Descender")!=0)) {
- wxLogDebug("AFM-file '%s': line '%s' has error (bad descender)\n",
- afmName,line);
- }
- }
- // JC 1.) check for UnderlinePosition
- else if(strncmp(line,"UnderlinePosition",17)==0){
- if((sscanf(line,"%s%lf",upString,&UnderlinePosition)!=2)
- || (strcmp(upString,"UnderlinePosition")!=0)) {
- wxLogDebug("AFM-file '%s': line '%s' has error (bad UnderlinePosition)\n",
- afmName,line);
- }
- }
- // JC 2.) check for UnderlineThickness
- else if(strncmp(line,"UnderlineThickness",18)==0){
- if((sscanf(line,"%s%lf",utString,&UnderlineThickness)!=2)
- || (strcmp(utString,"UnderlineThickness")!=0)) {
- wxLogDebug("AFM-file '%s': line '%s' has error (bad UnderlineThickness)\n",
- afmName,line);
- }
- }
- // JC 3.) check for EncodingScheme
- else if(strncmp(line,"EncodingScheme",14)==0){
- if((sscanf(line,"%s%s",utString,encString)!=2)
- || (strcmp(utString,"EncodingScheme")!=0)) {
- wxLogDebug("AFM-file '%s': line '%s' has error (bad EncodingScheme)\n",
- afmName,line);
- }
- else if (strncmp(encString, "AdobeStandardEncoding", 21))
- {
- wxLogDebug("AFM-file '%s': line '%s' has error (unsupported EncodingScheme %s)\n",
- afmName,line, encString);
- }
- }
- // B.) check for char-width
- else if(strncmp(line,"C ",2)==0){
- if(sscanf(line,"%s%d%s%s%d",
- cString,&ascii,semiString,WXString,&cWidth)!=5){
- wxLogDebug("AFM-file '%s': line '%s' has an error (bad character width)\n",afmName,line);
- }
- if(strcmp(cString,"C")!=0 || strcmp(semiString,";")!=0 ||
- strcmp(WXString,"WX")!=0){
- wxLogDebug("AFM-file '%s': line '%s' has a format error\n",afmName,line);
- }
- //printf(" char '%c'=%d has width '%d'\n",ascii,ascii,cWidth);
- if(ascii>=0 && ascii<256){
- lastWidths[ascii] = cWidth; // store width
- }else{
- /* MATTHEW: this happens a lot; don't print an error */
- // wxLogDebug("AFM-file '%s': ASCII value %d out of range\n",afmName,ascii);
- }
- }
- // C.) ignore other entries.
- }
- fclose(afmFile);
- }
- // hack to compute correct values for german 'Umlaute'
- // the correct way would be to map the character names
- // like 'adieresis' to corresp. positions of ISOEnc and read
- // these values from AFM files, too. Maybe later ...
- lastWidths[196] = lastWidths['A']; // Ä
- lastWidths[228] = lastWidths['a']; // ä
- lastWidths[214] = lastWidths['O']; // Ö
- lastWidths[246] = lastWidths['o']; // ö
- lastWidths[220] = lastWidths['U']; // Ü
- lastWidths[252] = lastWidths['u']; // ü
- lastWidths[223] = lastWidths[251]; // ß
- }
-
- // JC: calculate UnderlineThickness/UnderlinePosition
- m_underlinePosition = m_underlinePosition * fontToUse->GetPointSize() / 1000.0f;
- m_underlineThickness = m_underlineThickness * fontToUse->GetPointSize() / 1000.0f * m_scaleFactor;
-
- // 3. now the font metrics are read in, calc size *******************
- // this is done by adding the widths of the characters in the
- // string. they are given in 1/1000 of the size!
-
- long widthSum=0;
- long height=Size; // by default
- unsigned char *p;
- for(p=(unsigned char *)(const char *)string; *p; p++){
- if(lastWidths[*p]== INT_MIN){
- wxLogDebug("GetTextExtent: undefined width for character '%c' (%d)\n",
- *p,*p);
- widthSum += (long)(lastWidths[' ']/1000.0F * Size); // assume space
- }else{
- widthSum += (long)((lastWidths[*p]/1000.0F)*Size);
- }
- }
- // add descender to height (it is usually a negative value)
- if(lastDescender!=INT_MIN){
- height += (long)(((-lastDescender)/1000.0F) * Size); /* MATTHEW: forgot scale */
- }
-
- // return size values
- *x = widthSum;
- *y = height;
-
- // return other parameters
- if (descent){
- if(lastDescender!=INT_MIN){
- *descent = (long)(((-lastDescender)/1000.0F) * Size); /* MATTHEW: forgot scale */
- }else{
- *descent = 0;
- }
- }