📄 ttsbit.c
字号:
/***************************************************************************//* *//* ttsbit.c *//* *//* TrueType and OpenType embedded bitmap support (body). *//* *//* Copyright 1996-1999 by *//* David Turner, Robert Wilhelm, and Werner Lemberg. *//* *//* This file is part of the FreeType project, and may only be used *//* modified and distributed under the terms of the FreeType project *//* license, LICENSE.TXT. By continuing to use, modify, or distribute *//* this file you indicate that you have read the license and *//* understand and accept it fully. *//* *//* *//* WARNING: This file should not be compiled directly, it is meant to be *//* included in the source of several font drivers (i.e., the TTF *//* and OTF drivers). *//* *//***************************************************************************/#include <ftdebug.h>#include <ttsbit.h>#include <tttags.h>#include <tterrors.h> /*************************************************************************/ /* */ /* <Function> */ /* blit_sbit */ /* */ /* <Description> */ /* Blits a bitmap from an input stream into a given target. Supports */ /* x and y offsets as well as byte padded lines. */ /* */ /* <Input> */ /* target :: The target bitmap/pixmap. */ /* */ /* source :: The input packed bitmap data. */ /* */ /* line_bits :: The number of bits per line. */ /* */ /* byte_padded :: A flag which is true if lines are byte-padded. */ /* */ /* x_offset :: The horizontal offset. */ /* */ /* y_offset :: The vertical offset. */ /* */ /* <Note> */ /* IMPORTANT: The x and y offsets are relative to the top corner of */ /* the target bitmap (unlike the normal TrueType */ /* convention). A positive y offset indicates a downwards */ /* direction! */ /* */ static void blit_sbit( FT_Bitmap* target, char* source, FT_Int line_bits, FT_Bool byte_padded, FT_Int x_offset, FT_Int y_offset ) { FT_Byte* line_buff; FT_Int line_incr; FT_Int height; FT_UShort acc; FT_Byte loaded; /* first of all, compute starting write position */ line_incr = target->pitch; line_buff = target->buffer; if (line_incr < 0) line_buff -= line_incr*(target->rows-1); line_buff += (x_offset >> 3) + y_offset * line_incr; /***********************************************************************/ /* */ /* We use the extra-classic `accumulator' trick to extract the bits */ /* from the source byte stream. */ /* */ /* Namely, the variable `acc' is a 16-bit accumulator containing the */ /* last `loaded' bits from the input stream. The bits are shifted to */ /* the upmost position in `acc'. */ /* */ /***********************************************************************/ acc = 0; /* clear accumulator */ loaded = 0; /* no bits were loaded */ for ( height = target->rows; height > 0; height-- ) { FT_Byte* cur = line_buff; /* current write cursor */ FT_Int count = line_bits; /* # of bits to extract per line */ FT_Byte shift = x_offset & 7; /* current write shift */ FT_Byte space = 8 - shift; /* first of all, read individual source bytes */ if ( count >= 8 ) { count -= 8; { do { FT_Byte val; /* ensure that there are at least 8 bits in the accumulator */ if ( loaded < 8 ) { acc |= ((FT_UShort)*source++) << (8 - loaded); loaded += 8; } /* now write one byte */ val = (FT_Byte)(acc >> 8); if (shift) { cur[0] |= val >> shift; cur[1] |= val << space; } else cur[0] = val; cur++; acc <<= 8; /* remove bits from accumulator */ loaded -= 8; count -= 8; } while ( count >= 0 ); } /* restore `count' to correct value */ count += 8; } /* now write remaining bits (count < 8) */ if ( count > 0 ) { FT_Byte val; /* ensure that there are at least `count' bits in the accumulator */ if ( loaded < count ) { acc |= ((FT_UShort)*source++) << (8 - loaded); loaded += 8; } /* now write remaining bits */ val = ((FT_Byte)(acc >> 8)) & ~(0xFF >> count); cur[0] |= val >> shift; if ( count > space ) cur[1] |= val << space; acc <<= count; loaded -= count; } /* now, skip to next line */ if ( byte_padded ) acc = loaded = 0; /* clear accumulator on byte-padded lines */ line_buff += line_incr; } } /*************************************************************************/ /* */ /* <Function> */ /* TT_Load_Small_SBit_Metrics */ /* */ /* <Description> */ /* Loads a small bitmap metrics record. */ /* */ /* <Input> */ /* stream :: The input stream. */ /* */ /* <Output> */ /* metrics :: A small metrics structure. */ /* */ static void TT_Load_Small_SBit_Metrics( TT_SBit_Small_Metrics* metrics, FT_Stream stream ) { metrics->height = GET_Byte(); metrics->width = GET_Byte(); metrics->bearingX = GET_Char(); metrics->bearingY = GET_Char(); metrics->advance = GET_Byte(); } /*************************************************************************/ /* */ /* <Function> */ /* TT_Load_SBit_Metrics */ /* */ /* <Description> */ /* Loads a bitmap metrics record. */ /* */ /* <Input> */ /* stream :: The input stream. */ /* */ /* <Output> */ /* metrics :: A metrics structure. */ /* */ static void TT_Load_SBit_Metrics( TT_SBit_Metrics* metrics, FT_Stream stream ) { metrics->height = GET_Byte(); metrics->width = GET_Byte(); metrics->horiBearingX = GET_Char(); metrics->horiBearingY = GET_Char(); metrics->horiAdvance = GET_Byte(); metrics->vertBearingX = GET_Char(); metrics->vertBearingY = GET_Char(); metrics->vertAdvance = GET_Byte(); } /*************************************************************************/ /* */ /* <Function> */ /* TT_Load_SBit_Line_Metrics */ /* */ /* <Description> */ /* Loads a bitmap line metrics record. */ /* */ /* <Input> */ /* stream :: The input stream. */ /* */ /* <Output> */ /* metrics :: A line metrics structure. */ /* */ static void TT_Load_SBit_Line_Metrics( TT_SBit_Line_Metrics* metrics, FT_Stream stream ) { metrics->ascender = GET_Char(); metrics->descender = GET_Char(); metrics->max_width = GET_Byte(); metrics->caret_slope_numerator = GET_Char(); metrics->caret_slope_denominator = GET_Char(); metrics->caret_offset = GET_Char(); metrics->min_origin_SB = GET_Char(); metrics->min_advance_SB = GET_Char(); metrics->max_before_BL = GET_Char(); metrics->min_after_BL = GET_Char(); metrics->pads[0] = GET_Char(); metrics->pads[1] = GET_Char(); } /*************************************************************************/ /* */ /* <Function> */ /* TT_Load_SBit_Const_Metrics */ /* */ /* <Description> */ /* Loads the metrics for `EBLC' index tables format 2 and 5. */ /* */ /* <Input> */ /* range :: The target range. */ /* */ /* stream :: The input stream. */ /* */ /* <Return> */ /* TrueType error code. 0 means success. */ /* */ static TT_Error Load_SBit_Const_Metrics( TT_SBit_Range* range, FT_Stream stream ) { TT_Error error; if ( !ACCESS_Frame( 12L ) ) { range->image_size = GET_ULong(); TT_Load_SBit_Metrics( &range->metrics, stream ); FORGET_Frame(); } return error; } /*************************************************************************/ /* */ /* <Function> */ /* TT_Load_SBit_Range_Codes */ /* */ /* <Description> */ /* Loads the range codes for `EBLC' index tables format 4 and 5. */ /* */ /* <Input> */ /* range :: The target range. */ /* */ /* stream :: The input stream. */ /* */ /* load_offsets :: A flag whether to load the glyph offset table. */ /* */ /* <Return> */ /* TrueType error code. 0 means success. */ /* */ static TT_Error Load_SBit_Range_Codes( TT_SBit_Range* range, FT_Stream stream, TT_Bool load_offsets ) { TT_Error error; TT_ULong count, n, size; FT_Memory memory = stream->memory; if ( READ_ULong( count ) ) goto Exit; range->num_glyphs = count; /* Allocate glyph offsets table if needed */ if ( load_offsets ) { if ( ALLOC_ARRAY( range->glyph_offsets, count, TT_ULong ) ) goto Exit; size = count * 4L; } else size = count * 2L; /* Allocate glyph codes table and access frame */ if ( ALLOC_ARRAY ( range->glyph_codes, count, TT_UShort ) || ACCESS_Frame( size ) ) goto Exit; for ( n = 0; n < count; n++ ) { range->glyph_codes[n] = GET_UShort(); if (load_offsets) range->glyph_offsets[n] = (TT_ULong)range->image_offset + GET_UShort(); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -