📄 ttsbit.c
字号:
if ( range->index_format == 4 ) *aglyph_offset = range->glyph_offsets[n]; else *aglyph_offset = range->image_offset + n * range->image_size; break; } } } /* fall-through */ default: goto Fail; } /* return successfully! */ *arange = range; return 0; } } Fail: *arange = 0; *aglyph_offset = 0; return TT_Err_Invalid_Argument; } /*************************************************************************/ /* */ /* <Function> */ /* Find_SBit_Image */ /* */ /* <Description> */ /* Checks whether an embedded bitmap (an `sbit') exists for a given */ /* glyph, at given x and y ppems. */ /* */ /* <Input> */ /* face :: The target face object. */ /* glyph_index :: The glyph index. */ /* x_ppem :: The horizontal resolution in points per EM. */ /* y_ppem :: The vertical resolution in points per EM. */ /* */ /* <Output> */ /* arange :: The SBit range containing the glyph index. */ /* astrike :: The SBit strike containing the glyph index. */ /* aglyph_offset :: The offset of the glyph data in `EBDT' table. */ /* */ /* <Return> */ /* TrueType error code. 0 means success. Returns */ /* TT_Err_Invalid_Argument if no sbit exist for the requested glyph. */ /* */ static TT_Error Find_SBit_Image( TT_Face face, TT_UInt glyph_index, TT_Int x_ppem, TT_Int y_ppem, TT_SBit_Range** arange, TT_SBit_Strike** astrike, TT_ULong* aglyph_offset ) { TT_SBit_Strike* strike = face->sbit_strikes; TT_SBit_Strike* strike_limit = strike + face->num_sbit_strikes; if ( !strike) goto Fail; for ( ; strike < strike_limit; strike++ ) { if ( strike->x_ppem == x_ppem && strike->y_ppem == y_ppem ) { TT_Error error; error = Find_SBit_Range( glyph_index, strike, arange, aglyph_offset ); if ( error ) goto Fail; *astrike = strike; return TT_Err_Ok; } } Fail: /* no embedded bitmap for this glyph in face */ *arange = 0; *astrike = 0; *aglyph_offset = 0; return TT_Err_Invalid_Argument; } /*************************************************************************/ /* */ /* <Function> */ /* Load_SBit_Metrics */ /* */ /* <Description> */ /* Gets the big metrics for a given SBit. */ /* */ /* <Input> */ /* stream :: The input stream. */ /* range :: The SBit range containing the glyph. */ /* */ /* <Output> */ /* big_metrics :: A big SBit metrics structure for the glyph. */ /* */ /* <Return> */ /* TrueType error code. 0 means success. */ /* */ /* <Note> */ /* The stream cursor must be positioned at the glyph's offset within */ /* the `EBDT' table before the call. */ /* */ /* If the image format uses variable metrics, the stream cursor is */ /* positioned just after the metrics header in the `EBDT' table on */ /* function exit. */ /* */ static TT_Error Load_SBit_Metrics( FT_Stream stream, TT_SBit_Range* range, TT_SBit_Metrics* metrics ) { TT_Error error = TT_Err_Ok; switch ( range->index_format ) { case 1: /* variable metrics */ case 3: case 4: { switch ( range->image_format ) { case 1: /* small metrics */ case 2: case 8: { TT_SBit_Small_Metrics smetrics; /* read small metrics */ if ( ACCESS_Frame( 5L ) ) goto Exit; TT_Load_Small_SBit_Metrics( &smetrics, stream ); FORGET_Frame(); /* convert it to a big metrics */ metrics->height = smetrics.height; metrics->width = smetrics.width; metrics->horiBearingX = smetrics.bearingX; metrics->horiBearingY = smetrics.bearingY; metrics->horiAdvance = smetrics.advance; /* these metrics are made up at a higher level when */ /* needed. */ metrics->vertBearingX = 0; metrics->vertBearingY = 0; metrics->vertAdvance = 0; } break; default: /* big metrics */ if ( ACCESS_Frame( 8L ) ) goto Exit; TT_Load_SBit_Metrics( metrics, stream ); FORGET_Frame(); } } break; default: /* constant metrics */ *metrics = range->metrics; } Exit: return error; } /*************************************************************************/ /* */ /* <Function> */ /* Crop_Bitmap */ /* */ /* <Description> */ /* Crops a bitmap to its tightest bounding box, and adjusts its */ /* metrics. */ /* */ /* <Input> */ /* image :: The input glyph slot. */ /* */ /* metrics :: The corresponding metrics structure. */ /* */ static void Crop_Bitmap( FT_Bitmap* map, TT_SBit_Metrics* metrics ) { /***********************************************************************/ /* */ /* In this situation, some bounding boxes of embedded bitmaps are too */ /* large. We need to crop it to a reasonable size. */ /* */ /* --------- */ /* | | ----- */ /* | *** | |***| */ /* | * | | * | */ /* | * | ------> | * | */ /* | * | | * | */ /* | * | | * | */ /* | *** | |***| */ /* --------- ----- */ /* */ /***********************************************************************/ TT_Int rows, count; TT_Long line_len; TT_Byte* line; /***********************************************************************/ /* */ /* first of all, checks the top-most lines of the bitmap, and removes */ /* them if they're empty. */ /* */ { line = (TT_Byte*)map->buffer; rows = map->rows; line_len = map->pitch; for ( count = 0; count < rows; count++ ) { TT_Byte* cur = line; TT_Byte* limit = line + line_len; for ( ; cur < limit; cur++ ) if ( cur[0] ) goto Found_Top; /* the current line was empty - skip to next one */ line = limit; } Found_Top: /* check that we have at least one filled line */ if ( count >= rows ) goto Empty_Bitmap; /* now, crop the empty upper lines */ if ( count > 0 ) { line = (TT_Byte*)map->buffer; MEM_Move( line, line + count * line_len, (rows - count) * line_len ); metrics->height -= count; metrics->horiBearingY -= count; metrics->vertBearingY -= count; map->rows -= count; rows -= count; } } /***********************************************************************/ /* */ /* second, crop the lower lines */ /* */ { line = (TT_Byte*)map->buffer + (rows - 1) * line_len; for ( count = 0; count < rows; count++ ) { TT_Byte* cur = line; TT_Byte* limit = line + line_len; for ( ; cur < limit; cur++ ) if ( cur[0] ) goto Found_Bottom; /* the current line was empty - skip to previous one */ line -= line_len; } Found_Bottom: if ( count > 0 ) { metrics->height -= count; rows -= count; map->rows -= count; } } /***********************************************************************/ /* */ /* third, get rid of the space on the left side of the glyph */ /* */ do { TT_Byte* limit; line = (TT_Byte*)map->buffer; limit = line + rows * line_len; for ( ; line < limit; line += line_len ) if ( line[0] & 0x80 ) goto Found_Left; /* shift the whole glyph one pixel to the left */ line = (TT_Byte*)map->buffer; limit = line + rows * line_len; for ( ; line < limit; line += line_len ) { TT_Int n, width = map->width; TT_Byte old; TT_Byte* cur = line; old = cur[0] << 1; for ( n = 8; n < width; n += 8 ) { TT_Byte val; val = cur[1]; cur[0] = old | (val >> 7); old = val << 1; cur++; } cur[0] = old; } map->width--; metrics->horiBearingX++; metrics->vertBearingX++; metrics->width--; } while ( map->width > 0 ); Found_Left: /***********************************************************************/ /* */ /* finally, crop the bitmap width to get rid of the space on the right */ /* side of the glyph. */ /* */ do { TT_Int right = map->width-1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -