📄 t1set.c
字号:
If either glyph is NULL or the glyphs have distinct depth, NULL is returned. */GLYPH *T1_ConcatGlyphs( GLYPH *glyph_1, GLYPH *glyph_2, int x_off, int y_off, int modflag){ int lsb1, lsb2, rsb1, rsb2; int advanceX1, advanceX2, advanceY1, advanceY2; int ascent1, ascent2, descent1, descent2; int rsb, lsb, ascent, descent, advanceX, advanceY; int vanchor, w, h, wscanline, wscanline1, wscanline2, bpp; int memsize, BitShift; GLYPH *glyph1, *glyph2; unsigned T1_AA_TYPE16 BitBuf_c; unsigned T1_AA_TYPE32 BitBuf_s; unsigned long BitBuf_l; /* This is only actually used if sizeof long = 8 */ int i, j, k; int ByteOffset; unsigned char *Target_c, *p_c; unsigned T1_AA_TYPE16 *Target_s, *p_s; unsigned T1_AA_TYPE32 *Target_l, *p_l; static GLYPH glyph={NULL,{0,0,0,0,0,0},NULL,1}; /* We handle the Right-To-Left concatenation the simple way: 1) Change the order of the two glyphs 2) Invert the sign of the y-part of the offset 3) Recalculate the dimensions of the resulating glyph. */ /* Check for writing direction and reorganize appropriately: */ if (modflag & T1_RIGHT_TO_LEFT){ glyph1=glyph_2; glyph2=glyph_1; y_off=-y_off; } else { glyph1=glyph_1; glyph2=glyph_2; } if (glyph1==NULL){ T1_errno=T1ERR_INVALID_PARAMETER; return( NULL); } if (glyph2==NULL){ T1_errno=T1ERR_INVALID_PARAMETER; return( NULL); } if (glyph1->bpp != glyph2->bpp){ T1_errno=T1ERR_INVALID_PARAMETER; return( NULL); } /* We have two glyph different from NULL */ /* Reset glyph, if necessary */ if (glyph.bits!=NULL){ free(glyph.bits); glyph.bits=NULL; } glyph.metrics.leftSideBearing=0; glyph.metrics.rightSideBearing=0; glyph.metrics.advanceX=0; glyph.metrics.advanceY=0; glyph.metrics.ascent=0; glyph.metrics.descent=0; glyph.pFontCacheInfo=NULL; glyph.bpp=1; /* Assign dimens */ lsb1=glyph1->metrics.leftSideBearing; rsb1=glyph1->metrics.rightSideBearing; ascent1=glyph1->metrics.ascent; descent1=glyph1->metrics.descent; advanceX1=glyph1->metrics.advanceX + x_off; advanceY1=glyph1->metrics.advanceY + y_off; lsb2=glyph2->metrics.leftSideBearing; rsb2=glyph2->metrics.rightSideBearing; ascent2=glyph2->metrics.ascent; descent2=glyph2->metrics.descent; advanceX2=glyph2->metrics.advanceX; advanceY2=glyph2->metrics.advanceY; lsb=lsb1 < lsb2+advanceX1 ? lsb1 : lsb2+advanceX1; rsb=rsb1 > rsb2+advanceX1 ? rsb1 : rsb2+advanceX1; ascent=ascent1 > ascent2+advanceY1 ? ascent1 : ascent2+advanceY1; descent=descent1 < descent2+advanceY1 ? descent1 : descent2+advanceY1; advanceX=advanceX1+advanceX2; advanceY=advanceY1+advanceY2; bpp=glyph1->bpp; w=rsb-lsb; h=ascent-descent; wscanline=PAD( w*bpp, T1_pad) / 8; wscanline1=PAD( (rsb1-lsb1)*bpp, T1_pad) / 8; wscanline2=PAD( (rsb2-lsb2)*bpp, T1_pad) / 8; memsize=wscanline*h; if ((glyph.bits=(char *)calloc( memsize + 1, sizeof(unsigned char)))==NULL){ T1_errno=T1ERR_ALLOC_MEM; return(NULL); } if (bpp==1){ if (T1_pad==32 && T1_byte==0 && sizeof(long)==8){ /* The following loop steps through the lines of the first glyph: */ vanchor=ascent-ascent1; BitShift=(lsb1-lsb) % 32; ByteOffset=(lsb1-lsb)/32*4; for ( i=0; i<ascent1-descent1; i++){ Target_l= (unsigned T1_AA_TYPE32 *)(glyph.bits +((vanchor+i)*wscanline) +ByteOffset); p_l = (unsigned T1_AA_TYPE32 *)(glyph1->bits+(wscanline1*i)); if (BitShift == 0){ for (k=wscanline1/4; k; k--) *Target_l++ |= *p_l++; } else{ for (k=wscanline1/4; k; k--){ BitBuf_l = ((long)*p_l++) << BitShift; *Target_l++ |= BitBuf_l; *Target_l |= BitBuf_l>>l_shift; } } } /* The following loop steps through the lines of the second glyph: */ vanchor=ascent-(ascent2+advanceY1); BitShift=(lsb2+advanceX1-lsb) % 32; ByteOffset=(lsb2+advanceX1-lsb)/32*4; for ( i=0; i<ascent2-descent2; i++){ Target_l= (unsigned T1_AA_TYPE32 *)(glyph.bits +((vanchor+i)*wscanline) +ByteOffset); p_l = (unsigned T1_AA_TYPE32 *)(glyph2->bits+(wscanline2*i)); if (BitShift == 0){ for (k=wscanline2/4; k; k--) *Target_l++ |= *p_l++; } else{ for (k=wscanline2/4; k; k--){ BitBuf_l = ((long)*p_l++) << BitShift; *Target_l++ |= BitBuf_l; *Target_l |= BitBuf_l>>l_shift; } } } } else if(T1_pad==16 && T1_byte==0){ /* The following loop steps through the lines of the first glyph: */ vanchor=ascent-ascent1; BitShift=(lsb1-lsb) % 16; ByteOffset=(lsb1-lsb)/16*2; for ( i=0; i<ascent1-descent1; i++){ Target_s= (unsigned T1_AA_TYPE16 *)(glyph.bits +((vanchor+i)*wscanline) +ByteOffset); p_s = (unsigned T1_AA_TYPE16 *)(glyph1->bits+(wscanline1*i)); if (BitShift == 0){ for (k=wscanline1/2; k; k--) *Target_s++ |= *p_s++; } else{ for (k=wscanline1/2; k; k--){ BitBuf_s = ((T1_AA_TYPE32)*p_s++) << BitShift; *Target_s++ |= BitBuf_s; *Target_s |= BitBuf_s>>s_shift; } } } /* The following loop steps through the lines of the second glyph: */ vanchor=ascent-(ascent2+advanceY1); BitShift=(lsb2+advanceX1-lsb) % 16; ByteOffset=(lsb2+advanceX1-lsb)/16*2; for ( i=0; i<ascent2-descent2; i++){ Target_s= (unsigned T1_AA_TYPE16 *)(glyph.bits +((vanchor+i)*wscanline) +ByteOffset); p_s = (unsigned T1_AA_TYPE16 *)(glyph2->bits+(wscanline2*i)); if (BitShift == 0){ for (k=wscanline2/2; k; k--) *Target_s++ |= *p_s++; } else{ for (k=wscanline2/2; k; k--){ BitBuf_s = ((T1_AA_TYPE32)*p_s++) << BitShift; *Target_s++ |= BitBuf_s; *Target_s |= BitBuf_s>>s_shift; } } } } else{ /* T1_pad==8 or Big Endian machine */ /* The following loop steps through the lines of the first glyph: */ vanchor=ascent-ascent1; BitShift=(lsb1-lsb) % 8; ByteOffset=(lsb1-lsb) / 8; for ( i=0; i<ascent1-descent1; i++){ Target_c= (unsigned char *)(glyph.bits +((vanchor+i)*wscanline) +ByteOffset); p_c = (unsigned char *)(glyph1->bits+(wscanline1*i)); if (BitShift == 0){ for (k=wscanline1; k; k--) *Target_c++ |= *p_c++; } else{ for (k=wscanline1; k; k--){ BitBuf_c = ((T1_AA_TYPE16)*p_c++) << BitShift; *Target_c++ |= BitBuf_c; *Target_c |= BitBuf_c>>c_shift; } } } /* The following loop steps through the lines of the second glyph: */ vanchor=ascent-(ascent2+advanceY1); BitShift=(lsb2+advanceX1-lsb) % 8; ByteOffset=(lsb2+advanceX1-lsb) / 8; for ( i=0; i<ascent2-descent2; i++){ Target_c= (unsigned char *)(glyph.bits +((vanchor+i)*wscanline) +ByteOffset); p_c = (unsigned char *)(glyph2->bits+(wscanline2*i)); if (BitShift == 0){ for (k=wscanline2; k; k--) *Target_c++ |= *p_c++; } else{ for (k=wscanline2; k; k--){ BitBuf_c = ((T1_AA_TYPE16)*p_c++) << BitShift; *Target_c++ |= BitBuf_c; *Target_c |= BitBuf_c>>c_shift; } } } } } /* end of if (bpp==1) ... */ else if (bpp==8){ /* Set background */ for ( i=0; i<memsize; i++) ((char *)glyph.bits)[i]=(char) T1aa_bg; /* The following loop steps through the lines of the first glyph: */ vanchor=ascent-ascent1; for ( i=0; i<ascent1-descent1; i++){ Target_c= (unsigned char *)(glyph.bits +((vanchor+i)*wscanline) +(lsb1-lsb)); p_c = (unsigned char *)(glyph1->bits+(wscanline1*i)); memcpy( Target_c, p_c, (rsb1-lsb1)); } /* The following loop steps through the lines of the second glyph. Note that we only set the pixel if it is not background! */ vanchor=ascent-(ascent2+advanceY1); for ( i=0; i<ascent2-descent2; i++){ Target_c= (unsigned char *)(glyph.bits +((vanchor+i)*wscanline) +(lsb2+advanceX1-lsb)); p_c = (unsigned char *)(glyph2->bits+(wscanline2*i)); for (j=0; j<(rsb2-lsb2); j++) if (p_c[j] != (unsigned char) T1aa_bg) Target_c[j]=p_c[j]; } } /* end of if (bpp==8) ... */ else if (bpp==16){ /* Set background */ for ( i=0; i<memsize/2; i++) ((T1_AA_TYPE16 *)glyph.bits)[i]=(T1_AA_TYPE16) T1aa_bg; /* The following loop steps through the lines of the first glyph: */ vanchor=ascent-ascent1; for ( i=0; i<ascent1-descent1; i++){ Target_s= (unsigned T1_AA_TYPE16 *)(glyph.bits +((vanchor+i)*wscanline) +(lsb1-lsb)*2); p_s = (unsigned T1_AA_TYPE16 *)(glyph1->bits+(wscanline1*i)); memcpy( Target_s, p_s, (rsb1-lsb1)*2); } /* The following loop steps through the lines of the second glyph. Note that we only set the pixel if it is not background! */ vanchor=ascent-(ascent2+advanceY1); for ( i=0; i<ascent2-descent2; i++){ Target_s= (unsigned T1_AA_TYPE16 *)(glyph.bits +((vanchor+i)*wscanline) +(lsb2+advanceX1-lsb)*2); p_s = (unsigned T1_AA_TYPE16 *)(glyph2->bits+(wscanline2*i)); for (j=0; j<(rsb2-lsb2); j++) if (p_s[j] != (unsigned T1_AA_TYPE16) T1aa_bg) Target_s[j]=p_s[j]; } } /* end of if (bpp==16) ... */ else if (bpp==32){ /* Set background */ for ( i=0; i<memsize/4; i++) ((T1_AA_TYPE32 *)glyph.bits)[i]=(T1_AA_TYPE32) T1aa_bg; /* The following loop steps through the lines of the first glyph: */ vanchor=ascent-ascent1; for ( i=0; i<ascent1-descent1; i++){ Target_l= (unsigned T1_AA_TYPE32 *)(glyph.bits +((vanchor+i)*wscanline) +(lsb1-lsb)*4); p_l = (unsigned T1_AA_TYPE32 *)(glyph1->bits+(wscanline1*i)); memcpy( Target_l, p_l, (rsb1-lsb1)*4); } /* The following loop steps through the lines of the second glyph. Note that we only set the pixel if it is not background! */ vanchor=ascent-(ascent2+advanceY1); for ( i=0; i<ascent2-descent2; i++){ Target_l= (unsigned T1_AA_TYPE32 *)(glyph.bits +((vanchor+i)*wscanline) +(lsb2+advanceX1-lsb)*4); p_l = (unsigned T1_AA_TYPE32 *)(glyph2->bits+(wscanline2*i)); for (j=0; j<(rsb2-lsb2); j++) if (p_l[j] != (unsigned T1_AA_TYPE32) T1aa_bg) Target_l[j]=p_l[j]; } } /* end of if (bpp==32) ... */ /* Check for writing direction and re-compute dimens appropriately: */ if (modflag & T1_RIGHT_TO_LEFT){ advanceX=-advanceX1-advanceX2; advanceY=-advanceY1-advanceY2; lsb=lsb1 < lsb2+advanceX1 ? advanceX+lsb1 : advanceX+lsb2+advanceX1; rsb=rsb1 > rsb2+advanceX1 ? advanceX+rsb1 : advanceX+rsb2+advanceX1; ascent=ascent1 > ascent2+advanceY1 ? ascent1 : ascent2+advanceY1; descent=descent1 < descent2+advanceY1 ? descent1 : descent2+advanceY1; ascent += advanceY; descent += advanceY; } glyph.metrics.leftSideBearing=lsb; glyph.metrics.rightSideBearing=rsb; glyph.metrics.advanceX=advanceX; glyph.metrics.advanceY=advanceY; glyph.metrics.ascent=ascent; glyph.metrics.descent=descent; glyph.bpp=bpp; /* printf("lsb=%d, rsb=%d, adX=%d, adY=%d asc=%d, desc=%d\n", glyph.metrics.leftSideBearing, glyph.metrics.rightSideBearing, glyph.metrics.advanceX, glyph.metrics.advanceY, glyph.metrics.ascent, glyph.metrics.descent ); */ return( &glyph); }/* T1_FillOutline(): Create a filled glyph from an outline description */GLYPH *T1_FillOutline( T1_OUTLINE *path, int modflag){ struct region *area=NULL; static GLYPH glyph={NULL,{0,0,0,0,0,0},NULL,1}; volatile int memsize=0; int i; LONG h,w; LONG paddedW; /* We return to this if something goes wrong deep in the rasterizer */ if ((i=setjmp( stck_state))!=0) { T1_errno=T1ERR_TYPE1_ABORT; sprintf( err_warn_msg_buf, "t1_abort: Reason: %s", t1_get_abort_message( i)); T1_PrintLog( "T1_FillOutline()", err_warn_msg_buf, T1LOG_ERROR); return( NULL); } /* Reset character glyph, if necessary */ if (glyph.bits!=NULL){ free(glyph.bits); glyph.bits=NULL; } glyph.metrics.leftSideBearing=0; glyph.metrics.rightSideBearing=0; glyph.metrics.advanceX=0; glyph.metrics.advanceY=0; glyph.metrics.ascent=0; glyph.metrics.descent=0; glyph.pFontCacheInfo=NULL; glyph.bpp=1; /* Assign padding value */ T1_pad=pFontBase->bitmap_pad; if (pFontBase->endian) T1_byte=1; else T1_byte=0; T1_wordsize=T1_pad; /* Create a region from outline */ area=(struct region *)Interior( (struct segment *)path, WINDINGRULE+CONTINUITY); /* fill the glyph-structure */ if (area == NULL){ T1_PrintLog( "T1_FillOutline()", "area=NULL returned by Interior()", T1LOG_WARNING); T1_errno=1000; return(NULL); } h = area->ymax - area->ymin; w = area->xmax - area->xmin; paddedW = PAD(w, T1_pad); if ( (area->xmin > area->xmax) || (area->ymin > area->ymax) ){ /* There was a character like .notdef or space, that didn't produce any black pixels on the bitmap! -> we return a glyph with correct metrics and bitmap pointer set to NULL */ sprintf( err_warn_msg_buf, "No black pixels in outline %p", path); T1_PrintLog( "T1_FillOutline()", err_warn_msg_buf, T1LOG_WARNING); glyph.metrics.leftSideBearing = 0; glyph.metrics.advanceX = NEARESTPEL(area->ending.x - area->origin.x); glyph.metrics.advanceY = - NEARESTPEL(area->ending.y - area->origin.y); glyph.metrics.rightSideBearing = 0; glyph.metrics.descent = 0; glyph.metrics.ascent = 0; /* make sure to get rid of 'area' before leaving! */ KillRegion (area); return( &glyph); } 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 glyph.bits is free'ed every time this function is called: */ glyph.bits = (char *)malloc(memsize*sizeof( char)); if (glyph.bits == NULL){ T1_errno=T1ERR_ALLOC_MEM; /* make sure to get rid of area if it's there */ if (area){ KillRegion (area); } return(NULL); } } else { h = w = 0; area->xmin = area->xmax = 0; area->ymin = area->ymax = 0; } glyph.metrics.leftSideBearing = area->xmin; glyph.metrics.advanceX = NEARESTPEL(area->ending.x - area->origin.x); glyph.metrics.advanceY = - NEARESTPEL(area->ending.y - area->origin.y); glyph.metrics.rightSideBearing = area->xmax; glyph.metrics.descent = - area->ymax; glyph.metrics.ascent = - area->ymin; if (h > 0 && w > 0) { (void) memset(glyph.bits, 0, memsize); fill(glyph.bits, h, paddedW, area, T1_byte, T1_bit, T1_wordsize ); } /* Check for writing direction and re-compute dimensions appropriately: */ if (modflag & T1_RIGHT_TO_LEFT){ glyph.metrics.advanceX *= -1; glyph.metrics.advanceY *= -1; glyph.metrics.leftSideBearing += glyph.metrics.advanceX; glyph.metrics.rightSideBearing += glyph.metrics.advanceX; glyph.metrics.descent += glyph.metrics.advanceY; glyph.metrics.ascent += glyph.metrics.advanceY; } /* make sure to get rid of area if it's there */ if (area){ KillRegion (area); } return( &glyph); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -