📄 t1set.c
字号:
} } /* if (string_glyph.bits != NULL) */ /* We now put the underlining rule on the glyph */ if (modflag & T1_UNDERLINE){ start=-string_glyph.metrics.leftSideBearing; for (i=string_glyph.metrics.ascent-underline_starty; i<string_glyph.metrics.ascent-underline_endy; i++){ start =-string_glyph.metrics.leftSideBearing + (int) floor((double)(string_glyph.metrics.ascent-i) *fontarrayP->slant+0.5); middle = ((start+string_glyph.metrics.advanceX) / 8) - (start / 8); startmask = 0xFF << (start % 8); endmask = (char) ~(0xFF << ((start+string_glyph.metrics.advanceX) % 8)); Target_c= (unsigned char *)(string_glyph.bits +(i*paddedW/8) + (start / 8)); j=middle; if (j == 0) *Target_c++ |= startmask & endmask; else { *Target_c++ |= startmask; while (--j > 0) *Target_c++ = (unsigned char) 0xFF; if ((endmask)) *Target_c |= endmask; } } } /* Put an overstrike rule on the glyph */ if (modflag & T1_OVERSTRIKE){ start=-string_glyph.metrics.leftSideBearing; for (i=string_glyph.metrics.ascent-overstrike_starty; i<string_glyph.metrics.ascent-overstrike_endy; i++){ start =-string_glyph.metrics.leftSideBearing + (int) floor((double)(string_glyph.metrics.ascent-i) *fontarrayP->slant+0.5); middle = ((start+string_glyph.metrics.advanceX) / 8) - (start / 8); startmask = 0xFF << (start % 8); endmask = (char) ~(0xFF << ((start+string_glyph.metrics.advanceX) % 8)); Target_c= (unsigned char *)(string_glyph.bits +(i*paddedW/8) + (start / 8)); j=middle; if (j == 0) *Target_c++ |= startmask & endmask; else { *Target_c++ |= startmask; while (--j > 0) *Target_c++ = (unsigned char) 0xFF; if ((endmask)) *Target_c |= endmask; } } } /* Put an overline rule */ if (modflag & T1_OVERLINE){ start=-string_glyph.metrics.leftSideBearing; for (i=string_glyph.metrics.ascent-overline_starty; i<string_glyph.metrics.ascent-overline_endy; i++){ start =-string_glyph.metrics.leftSideBearing + (int) floor((double)(string_glyph.metrics.ascent-i) *fontarrayP->slant+0.5); middle = ((start+string_glyph.metrics.advanceX) / 8) - (start / 8); startmask = 0xFF << (start % 8); endmask = (char) ~(0xFF << ((start+string_glyph.metrics.advanceX) % 8)); Target_c= (unsigned char *)(string_glyph.bits +(i*paddedW/8) + (start / 8)); j=middle; if (j == 0) *Target_c++ |= startmask & endmask; else { *Target_c++ |= startmask; while (--j > 0) *Target_c++ = (unsigned char) 0xFF; if ((endmask)) *Target_c |= endmask; } } } /* Check for writing direction and re-compute dimensions appropriately: */ if (modflag & T1_RIGHT_TO_LEFT){ string_glyph.metrics.advanceX *= -1; string_glyph.metrics.leftSideBearing += string_glyph.metrics.advanceX; string_glyph.metrics.rightSideBearing += string_glyph.metrics.advanceX; } return(&string_glyph); } /* end of "if (rot_flag==0.0)" */ /* fnt_ptr now points to the correct FontSizeDeps-struct => lets now raster the character */ mode=0; kern_pairs=(int *)calloc(no_chars, sizeof(int)); if ((modflag & T1_KERNING)) for (i=0; i<no_chars -1; i++) kern_pairs[i]=T1_GetKerning( FontID, ustring[i], ustring[i+1]); area=fontfcnB_string( FontID, modflag, Current_S, fontarrayP->pFontEnc, ustring, no_chars, &mode, fontarrayP->pType1Data, kern_pairs, spacewidth, DO_RASTER); KillSpace (Current_S); /* In all cases, free memory for kerning pairs */ free(kern_pairs); /* fill the string_glyph-structure */ if (mode > 0) { sprintf( err_warn_msg_buf, "fontfcnB() set mode=%d", mode); T1_PrintLog( "T1_SetString()", err_warn_msg_buf, T1LOG_WARNING); T1_errno=mode; /* make sure to get rid of area if it's there */ if (area){ KillRegion (area); } return(NULL); } if (area == NULL){ T1_PrintLog( "T1_SetString()", "area=NULL returned by fontfcnB()", T1LOG_WARNING); T1_errno=mode; return(NULL); } if (mode == FF_NOTDEF_SUBST) { sprintf( err_warn_msg_buf, "\".notdef\" substituted somewhere in string from font %d", FontID); T1_PrintLog( "T1_SetString()", err_warn_msg_buf, T1LOG_WARNING); mode=0; } h = area->ymax - area->ymin; w = area->xmax - area->xmin; paddedW = PAD(w, T1_pad); if (h > 0 && w > 0) { memsize = h * paddedW / 8 + 1; /* This is for the users copy of the character, for security-reasons the original pointer to the cache area is not used. The entry string_glyph.bits is free'ed every time this function is called: */ string_glyph.bits = (char *)malloc(memsize*sizeof( char)); if (string_glyph.bits == NULL) { T1_errno=T1ERR_ALLOC_MEM; /* make sure to get rid of area if it's there */ if (area){ KillRegion (area); } /* it's safe to free this, since this is a rotated glyph and therefore it's a copy of the original one */ return(NULL); } } else { h = w = 0; area->xmin = area->xmax = 0; area->ymin = area->ymax = 0; } string_glyph.metrics.leftSideBearing=area->xmin; string_glyph.metrics.advanceX=NEARESTPEL(area->ending.x - area->origin.x); string_glyph.metrics.advanceY=-NEARESTPEL(area->ending.y - area->origin.y); string_glyph.metrics.rightSideBearing=area->xmax; string_glyph.metrics.descent=-area->ymax; string_glyph.metrics.ascent=-area->ymin; if (h > 0 && w > 0) { (void) memset(string_glyph.bits, 0, memsize); fill(string_glyph.bits, h, paddedW, area, T1_byte, T1_bit, T1_wordsize ); } else { /* We have no black pixels */ string_glyph.metrics.leftSideBearing=0; string_glyph.metrics.advanceX=NEARESTPEL(area->ending.x - area->origin.x); string_glyph.metrics.advanceY=-NEARESTPEL(area->ending.y - area->origin.y); string_glyph.metrics.rightSideBearing=0; string_glyph.metrics.descent=0; string_glyph.metrics.ascent=0; } /* make sure to get rid of area if it's there */ if (area){ KillRegion (area); } /* Check for writing direction and re-compute dimensions appropriately: */ if (modflag & T1_RIGHT_TO_LEFT){ string_glyph.metrics.advanceX *= -1; string_glyph.metrics.advanceY *= -1; string_glyph.metrics.leftSideBearing += string_glyph.metrics.advanceX; string_glyph.metrics.rightSideBearing += string_glyph.metrics.advanceX; string_glyph.metrics.descent += string_glyph.metrics.advanceY; string_glyph.metrics.ascent += string_glyph.metrics.advanceY; } return(&string_glyph);}void fill(dest, h, w, area, byte, bit, wordsize) register char *dest; /* destination bitmap */ int h,w; /* dimensions of 'dest', w padded */ register struct region *area; /* region to write to 'dest' */ int byte,bit; /* flags; LSBFirst or MSBFirst */ int wordsize; /* number of bits per word for LSB/MSB purposes */{ register struct edgelist *edge; /* for looping through edges */ register char *p; /* current scan line in 'dest' */ register int y; /* for looping through scans */ register int wbytes = w / 8; /* number of bytes in width */ register pel *leftP,*rightP; /* pointers to X values, left and right */ int xmin = area->xmin; /* upper left X */ int ymin = area->ymin; /* upper left Y */ for (edge = area->anchor; VALIDEDGE(edge); edge = edge->link->link) { p = dest + (edge->ymin - ymin) * wbytes; leftP = edge->xvalues; rightP = edge->link->xvalues; for (y = edge->ymin; y < edge->ymax; y++) { fillrun(p, *leftP++ - xmin , *rightP++ - xmin, bit); p += wbytes; } } /* Now, as an afterthought, we'll go reorganize if odd byte order requires it: */ /* We do not reorganize since t1lib internally always uses LSBFirst */ /* if ( 0 && wordsize != 8) { register int i; printf("Reorganizing data ..\n"); switch (wordsize) { case 16: { register unsigned short data,*p; p = (unsigned short *) dest; for (i = h * w /16; --i >= 0;) { data = *p; *p++ = (data << 8) + (data >> 8); } break; } case 64: case 32: { register ULONG data,*p; p = (ULONG *) dest; for (i = h * w / 32; --i >= 0;) { data = *p; *p++ = (data << 24) + (data >> 24) + (0xFF00 & (data >> 8)) + (0xFF0000 & (data << 8)); } if (wordsize == 64) { p = (ULONG *) dest; for (i = h * w / 64; --i >= 0;) { data = *p++; p[-1] = p[0]; *p++ = data; } } break; } default: abort("xiFill: unknown format"); } } */}#define ALLONES 0xFFvoid fillrun(register char *p, pel x0, pel x1, int bit){ register int startmask,endmask; /* bits to set in first and last char*/ register int middle; /* number of chars between start and end + 1 */ if (x1 <= x0) return; middle = x1/8 - x0/8; p += x0/8; x0 &= 7; x1 &= 7; if (bit == LSBFirst) { startmask = ALLONES << x0; endmask = ~(ALLONES << x1); } else { startmask = ALLONES >> x0; endmask = ~(ALLONES >> x1); } if (middle == 0) *p++ |= startmask & endmask; else { *p++ |= startmask; while (--middle > 0){ *p++ = (unsigned char)ALLONES; } if (endmask) *p |= endmask; }}/* outline */#undef CHECK_OUTLINEFILL#ifdef CHECK_OUTLINEFILLvoid fill(dest, h, w, area, byte, bit, wordsize) register char *dest; /* destination bitmap */ int h,w; /* dimensions of 'dest', w padded */ register struct region *area; /* region to write to 'dest' */ int byte,bit; /* flags; LSBFirst or MSBFirst */ int wordsize; /* number of bits per word for LSB/MSB purposes */{ register struct edgelist *edge; /* for looping through edges */ register char *p; /* current scan line in 'dest' */ register int y; /* for looping through scans */ register int wbytes = w / 8; /* number of bytes in width */ register pel *leftP,*rightP; /* pointers to X values, left and right */ int xmin = area->xmin; /* upper left X */ int ymin = area->ymin; /* upper left Y */ for (edge = area->anchor; VALIDEDGE(edge); edge = edge->link->link) { p = dest + (edge->ymin - ymin) * wbytes; leftP = edge->xvalues; rightP = edge->link->xvalues; printf("leftP=%d, RightP=%d,\n", *leftP, *rightP); for (y = edge->ymin; y < edge->ymax; y++) { printf("leftP=%d, RightP=%d,y=%d\n", *leftP, *rightP, y); fillrun(p, *leftP++ - xmin, *rightP++ - xmin, bit); p += wbytes; } }}#endif/* T1_CopyGlyph(): Make a copy of an existent glyph-structure to save it for later usage by the user. */GLYPH *T1_CopyGlyph( GLYPH *glyph){ GLYPH *dest; long size; if (glyph==NULL){ T1_errno=T1ERR_INVALID_PARAMETER; return(NULL); } /* Assign padding value */ T1_pad=pFontBase->bitmap_pad; /* Allocate memory for struct: */ if ((dest=(GLYPH *)malloc(sizeof(GLYPH)))==NULL){ T1_errno=T1ERR_ALLOC_MEM; return(NULL); } /* Copy the structure members: */ *dest=*glyph; /* Allocate memory for bitmap, initialize pointer to it and copy bitmap: */ size=PAD((dest->metrics.rightSideBearing-dest->metrics.leftSideBearing)* glyph->bpp, T1_pad) / 8; size=size*(dest->metrics.ascent-dest->metrics.descent); /* We must check whether there's actually a bits-pointer different from NULL. If not omit the following step: */ if (glyph->bits!=NULL){ if ((dest->bits=(char *)malloc(size*sizeof(char)))==NULL){ free(dest); T1_errno=T1ERR_ALLOC_MEM; return(NULL); } memcpy(dest->bits,glyph->bits,size); } return(dest);}/* T1_DumpGlyph(): Dump a glyph-representation to stdout: */void T1_DumpGlyph( GLYPH *glyph){ int i,j,h,w; /* i=line-index, j=column-index */ long paddedW; printf("Dataformat: T1_bit=%d, T1_byte=%d, T1_wordsize=%d, T1_pad=%d\n", T1_bit, T1_byte, T1_pad, T1_pad); if (glyph==NULL){ return; } h=glyph->metrics.ascent-glyph->metrics.descent; w=glyph->metrics.rightSideBearing-glyph->metrics.leftSideBearing; paddedW=PAD(w,T1_pad); printf("GlyphInfo: h=%d, w=%d, paddedW=%ld\n", h, w, paddedW); for ( i=0; i<h; i++){ if (T1_pad==8) for (j=0; j<paddedW/T1_pad; j++) bin_dump_c(glyph->bits[i*paddedW/T1_pad+j], 1); else if (T1_pad==16) for (j=0; j<paddedW/T1_pad; j++){ bin_dump_s(((unsigned short *)glyph->bits)[i*paddedW/T1_pad+j], 1); } else for (j=0; j<paddedW/T1_pad; j++){ bin_dump_l(((unsigned long *)glyph->bits)[i*paddedW/T1_pad+j], 1); } printf("\n"); } } /* This function will essentially return the bounding box of the line-rule */void T1_ComputeLineParameters( int FontID, int mode, int width, float size, int *startx, int *endx, int *starty, int *endy){ float position=0.0, thickness=0.0; int startx1, startx2, endx1, endx2; if (mode & T1_UNDERLINE){ position=pFontBase->pFontArray[FontID].UndrLnPos * DeviceSpecifics.scale_y; thickness=pFontBase->pFontArray[FontID].UndrLnThick * DeviceSpecifics.scale_y; } else if (mode & T1_OVERLINE){ position=pFontBase->pFontArray[FontID].OvrLnPos * DeviceSpecifics.scale_y; thickness=pFontBase->pFontArray[FontID].OvrLnThick * DeviceSpecifics.scale_y; } else if (mode & T1_OVERSTRIKE){ position=pFontBase->pFontArray[FontID].OvrStrkPos * DeviceSpecifics.scale_y; thickness=pFontBase->pFontArray[FontID].OvrStrkThick * DeviceSpecifics.scale_y; } *starty=(int) floor((position+0.5*(thickness-DeviceSpecifics.y_resolution/1000.0)) *size/1000.0 +0.5 ); startx1=(int) floor(*starty*pFontBase->pFontArray[FontID].slant+0.5); *endy =*starty - (int) floor(thickness/1000.0*size+0.5); startx2=(int) floor(*endy*pFontBase->pFontArray[FontID].slant+0.5); *startx=startx1 < startx2 ? startx1 : startx2; endx1 = width + (int) floor(*starty*pFontBase->pFontArray[FontID].slant+0.5); endx2 = width + (int) floor(*endy*pFontBase->pFontArray[FontID].slant+0.5); *endx=endx1 < endx2 ? endx2 : endx1; /* We take care that at least one pixel is drawn */ if (*starty==*endy) *endy -=1; return;}/* The following function concatenates two glyphs. Optional offsets x_off, y_off are respected. By the function.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -