📄 t1finfo.c
字号:
metrics.numchars=0; if (metrics.charpos != NULL){ free( metrics.charpos); metrics.charpos=NULL; } /* First, check for a correct ID */ i=CheckForFontID(FontID); if (i!=1){ T1_errno=T1ERR_INVALID_FONTID; return(metrics); } /* If no AFM info is present, we return an error */ if (pFontBase->pFontArray[FontID].pAFMData==NULL) { T1_errno=T1ERR_NO_AFM_DATA; return( metrics); } /* Get length of string: */ if (len<0 || ustring==NULL ) { /* invalid length or NULL_pointer */ T1_errno=T1ERR_INVALID_PARAMETER; return(metrics); } if (len==0) /* should be computed assuming "normal" 0-terminated string */ no_chars=strlen(string); else /* use value given on command line */ no_chars=len; /* Compute the correct spacewidth value (in charspace units): */ spacewidth=T1_GetCharWidth(FontID,pFontBase->pFontArray[FontID].space_position)+spaceoff; /* Allocate memory for character positions array: */ metrics.charpos=(int *)calloc(no_chars, sizeof(int)); metrics.numchars=no_chars; /* Accumulate metrics: */ for (i=0; i<no_chars; i++){ /* Save current offst to array */ metrics.charpos[i]=curr_width; if (string[i]==pFontBase->pFontArray[FontID].space_position) curr_width +=spacewidth; else{ tmp_BBox=T1_GetCharBBox( FontID, string[i]); if (curr_width+tmp_BBox.llx < lsb_min) lsb_min=curr_width+tmp_BBox.llx; if (curr_width+tmp_BBox.urx > rsb_max) rsb_max=curr_width+tmp_BBox.urx; if (tmp_BBox.lly < overalldescent) overalldescent=tmp_BBox.lly; if (tmp_BBox.ury > overallascent) overallascent=tmp_BBox.ury; curr_width +=T1_GetCharWidth( FontID, string[i]); if ((i<no_chars-1) && (kerning != 0)) curr_width += T1_GetKerning( FontID, string[i], string[i+1]); } } metrics.width =curr_width; metrics.bbox.llx=lsb_min; metrics.bbox.lly=overalldescent; metrics.bbox.urx=rsb_max; metrics.bbox.ury=overallascent; return( metrics); }/* T1_GetFontBBox(): Return the font's bounding box. Note: The font BBox is taken is taken from the font file rather than from afm file since I have seen some afm with rather inaccurate BBoxes.: */BBox T1_GetFontBBox( int FontID){ BBox outbox= { 0, 0, 0, 0}; struct ps_obj *obj; /* return Null-box if font not loaded */ if (CheckForFontID(FontID)!=1){ T1_errno=T1ERR_INVALID_FONTID; return(outbox); } /* As suggested by Derek B. Noonburg (xpdf-Author), we allow the FontBBox also to be specified by real numbers. */ obj = &(pFontBase->pFontArray[FontID].pType1Data->fontInfoP[FONTBBOX].value.data.arrayP[0]); outbox.llx = objPIsInteger(obj) ? obj->data.integer : obj->data.real > 0 ? (int) ceil(obj->data.real) : (int) floor(obj->data.real); obj = &(pFontBase->pFontArray[FontID].pType1Data->fontInfoP[FONTBBOX].value.data.arrayP[1]); outbox.lly = objPIsInteger(obj) ? obj->data.integer : obj->data.real > 0 ? (int) ceil(obj->data.real) : (int) floor(obj->data.real); obj = &(pFontBase->pFontArray[FontID].pType1Data->fontInfoP[FONTBBOX].value.data.arrayP[2]); outbox.urx = objPIsInteger(obj) ? obj->data.integer : obj->data.real > 0 ? (int) ceil(obj->data.real) : (int) floor(obj->data.real); obj = &(pFontBase->pFontArray[FontID].pType1Data->fontInfoP[FONTBBOX].value.data.arrayP[3]); outbox.ury = objPIsInteger(obj) ? obj->data.integer : obj->data.real > 0 ? (int) ceil(obj->data.real) : (int) floor(obj->data.real); return( outbox);} /* T1_GetAllCharNames(): Get a list of all defined character names in in the font FontID: */char **T1_GetAllCharNames( int FontID){ static char **bufmem=NULL; register char *namedest; psdict *pCharStrings; int len, i, j; long nameoffset; int bufmemsize=0; /* return NULL if font not loaded */ if (CheckForFontID(FontID)!=1){ T1_errno=T1ERR_INVALID_FONTID; return( NULL); } pCharStrings=pFontBase->pFontArray[FontID].pType1Data->CharStringsP; /* First, get number of charstrings: */ len=pCharStrings[0].key.len; /* We must be careful here: size of the charstrings dict might be larger than the actual number of charstrings. We correct for this by reducing the value of len appropriately */ for ( i=1; i<=len; i++){ /* calculate room for each characters name plus the prepending \0 */ if ((j=pCharStrings[i].key.len)){ bufmemsize += j + 1; } else{ /* we skip this (the remaining) entries */ len--; i--; } } /* Now we reserve memory for the pointers (including final NULL) */ nameoffset=(len+1)*sizeof( char *); bufmemsize += nameoffset; /* Now allocate memory, copy strings and initialize pointers */ if (bufmem!=NULL) free(bufmem); if ((bufmem=(char **)malloc( bufmemsize))==NULL){ T1_errno=T1ERR_ALLOC_MEM; return(NULL); } namedest=(char *)((long)bufmem + nameoffset); j=0; for ( i=0; i<len; i++){ bufmem[i]=&(namedest[j]); strncpy( &(namedest[j]), pCharStrings[i+1].key.data.nameP, pCharStrings[i+1].key.len); j += pCharStrings[i+1].key.len; namedest[j++]='\0'; } bufmem[i++]=NULL; return( bufmem); }/* T1_GetNoKernPairs(): Return the number of kerning pairs defined for font FontID */int T1_GetNoKernPairs( int FontID){ /* Check whether font is loaded: */ if (CheckForFontID(FontID)!=1){ T1_errno=T1ERR_INVALID_FONTID; return( -1); } /* If no AFM info is present, we return an error */ if (pFontBase->pFontArray[FontID].pAFMData==NULL) { T1_errno=T1ERR_NO_AFM_DATA; return( -1); } return( pFontBase->pFontArray[FontID].pAFMData->numOfPairs); }/* A function for comparing METRICS_ENTRY structs */static int cmp_METRICS_ENTRY( const void *entry1, const void *entry2){ if (((METRICS_ENTRY *)entry1)->chars < ((METRICS_ENTRY *)entry2)->chars) return(-1); if (((METRICS_ENTRY *)entry1)->chars > ((METRICS_ENTRY *)entry2)->chars) return(1); return(0); /* This should not happen */}/* A few functions for accessing composite character data: *//* T1_GetNoCompositeChars(): Return the number of characters for for which composite character information is available for font FontID */int T1_GetNoCompositeChars( int FontID){ /* Check whether font is loaded: */ if (CheckForFontID(FontID)!=1){ T1_errno=T1ERR_INVALID_FONTID; return( -1); } /* If no AFM info is present, we return an error */ if (pFontBase->pFontArray[FontID].pAFMData==NULL) { T1_errno=T1ERR_NO_AFM_DATA; return( -1); } return( pFontBase->pFontArray[FontID].pAFMData->numOfComps); }/* T1_QueryCompositeChar(): Query whether char1 from font FontID is a composite character. If so, the index of the composite character data within the afm array is returned. The index can be used to retrieve the retrieve the composite character data. retval>=0: index into AFM-array where the corresponding composite char data is located retval=-1: No composite character, but result is valid, retval=-2: No composite character, but result is invalid. T1_errno indicated the reason.*/int T1_QueryCompositeChar( int FontID, char char1) { unsigned char uchar1; uchar1=char1; /* Check whether font is loaded: */ if (CheckForFontID(FontID)!=1){ T1_errno=T1ERR_INVALID_FONTID; return( -2); } /* If no AFM info is present, we return -2 */ if (pFontBase->pFontArray[FontID].pAFMData==NULL) { T1_errno=T1ERR_NO_AFM_DATA; return( -2); } if (pFontBase->pFontArray[FontID].pEncMap[ uchar1]<0) { /* composite char */ return( -(pFontBase->pFontArray[FontID].pEncMap[(int) uchar1]+1)); } return(-1); }/* T1_GetCompCharData(): Retrieve data to construct composite character char1 from font FontID. In case of an error NULL is returned and T1_errno is set appropriately. */T1_COMP_CHAR_INFO *T1_GetCompCharData( int FontID, char char1){ T1_COMP_CHAR_INFO *cci=NULL; CompCharData *ccd=NULL; int afmind=-1; int i; unsigned char uchar1; /* Check whether font is loaded: */ if (CheckForFontID(FontID)!=1){ T1_errno=T1ERR_INVALID_FONTID; return( cci); } /* If no AFM info is present, we return -2 */ if (pFontBase->pFontArray[FontID].pAFMData==NULL) { T1_errno=T1ERR_NO_AFM_DATA; return( cci); } if ((cci=(T1_COMP_CHAR_INFO*)malloc( sizeof(T1_COMP_CHAR_INFO)))==NULL) { T1_errno=T1ERR_ALLOC_MEM; return( cci); } uchar1=(unsigned char)char1; /* set default values */ cci->compchar=uchar1; cci->numPieces=1; cci->pieces=NULL; /* check char1 */ if ((afmind=pFontBase->pFontArray[FontID].pEncMap[uchar1]) >= 0) { /* char is no composite char */ return(cci); } /* character is a composite char-> retrieve index and pointer into AFM data */ afmind=-(afmind+1); ccd=&(pFontBase->pFontArray[FontID].pAFMData->ccd[afmind]); /* cci->compchar is already setup correctly because char1 is a composite character */ cci->numPieces=ccd->numOfPieces; /* we expect numPieces to be >1 */ if ((cci->pieces=(T1_COMP_PIECE *)malloc( sizeof(T1_COMP_PIECE)* cci->numPieces))==NULL) { T1_errno=T1ERR_ALLOC_MEM; free( cci); return( NULL); } /* Copy information */ for (i=0; i<cci->numPieces; i++) { cci->pieces[i].piece=T1_GetEncodingIndex( FontID, ccd->pieces[i].pccName); cci->pieces[i].deltax=ccd->pieces[i].deltax; cci->pieces[i].deltay=ccd->pieces[i].deltay; } return( cci); }/* T1_GetCompCharDataByIndex(): Retrieve data to construct composite characters form font FontID. The data is addressed by index which may, for example, have been obtained by a call to T1_QueryCompositeChar(). In case of error NULL is returned and T1_errno is set appropriately.*/T1_COMP_CHAR_INFO *T1_GetCompCharDataByIndex( int FontID, int index){ T1_COMP_CHAR_INFO *cci=NULL; CompCharData *ccd=NULL; int i; /* Check whether font is loaded: */ if (CheckForFontID(FontID)!=1){ T1_errno=T1ERR_INVALID_FONTID; return( cci); } /* If no AFM info is present, we return -2 */ if (pFontBase->pFontArray[FontID].pAFMData==NULL) { T1_errno=T1ERR_NO_AFM_DATA; return( cci); } /* range check for index */ if ((index < 0) || (index >= pFontBase->pFontArray[FontID].pAFMData->numOfComps)) { T1_errno=T1ERR_INVALID_PARAMETER; return( cci); } /* Alloc mem */ if ((cci=(T1_COMP_CHAR_INFO*)malloc( sizeof(T1_COMP_CHAR_INFO)))==NULL) { T1_errno=T1ERR_ALLOC_MEM; return( cci); } /* set source pointer */ ccd=&(pFontBase->pFontArray[FontID].pAFMData->ccd[index]); /* and copy information */ cci->compchar=T1_GetEncodingIndex( FontID, ccd->ccName); cci->numPieces=ccd->numOfPieces; /* we expect numPieces to be >1 */ if ((cci->pieces=(T1_COMP_PIECE *)malloc( sizeof(T1_COMP_PIECE)* cci->numPieces))==NULL) { T1_errno=T1ERR_ALLOC_MEM; free( cci); return( NULL); } /* Copy information */ for (i=0; i<cci->numPieces; i++) { cci->pieces[i].piece=T1_GetEncodingIndex( FontID, ccd->pieces[i].pccName); cci->pieces[i].deltax=ccd->pieces[i].deltax; cci->pieces[i].deltay=ccd->pieces[i].deltay; } return( cci); }/* T1_IsInternalChar(): Query whether the character in encoding slot char1 of font FontID has an internal definition (CharString) or whether it is constructed by t1lib from elementary units */int T1_IsInternalChar( int FontID, char char1){ unsigned char uchar1; char *charname; psdict *pCharStrings; int len, i, j; /* return NULL if font not loaded */ if (CheckForFontID(FontID)!=1){ T1_errno=T1ERR_INVALID_FONTID; return( -1); } pCharStrings=pFontBase->pFontArray[FontID].pType1Data->CharStringsP; uchar1=(unsigned char)char1; charname=T1_GetCharName( FontID, uchar1); /* First, get the maximum number of charstrings: */ len=pCharStrings[0].key.len; /* Check all CharString definitions */ for ( i=1; i<=len; i++) { /* if len=0, then the CharStrings dict is larger that required which is valid and allowed by the spec.*/ if ((j=pCharStrings[i].key.len)!=0) { if ( (j==strlen(charname)) && (strncmp( charname, pCharStrings[i].key.data.nameP, j)==0) ) { /* we have found an internal definition */ return( 1); } } } return( 0);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -