📄 ttsbit.c
字号:
/***************************************************************************//* *//* ttsbit.c *//* *//* TrueType and OpenType embedded bitmap support (body). *//* *//* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007 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. *//* *//***************************************************************************/#include <ft2build.h>#include FT_INTERNAL_DEBUG_H#include FT_INTERNAL_STREAM_H#include FT_TRUETYPE_TAGS_H /* * Alas, the memory-optimized sbit loader can't be used when implementing * the `old internals' hack */#if !defined FT_CONFIG_OPTION_OLD_INTERNALS#include "ttsbit0.c"#else /* !FT_CONFIG_OPTION_OLD_INTERNALS */#include <ft2build.h>#include FT_INTERNAL_DEBUG_H#include FT_INTERNAL_STREAM_H#include FT_TRUETYPE_TAGS_H#include "ttsbit.h"#include "sferrors.h" /*************************************************************************/ /* */ /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ /* messages during execution. */ /* */#undef FT_COMPONENT#define FT_COMPONENT trace_ttsbit /*************************************************************************/ /* */ /* <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, FT_Byte* 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_UInt 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 = (FT_Byte)( x_offset & 7 ); /* current write shift */ FT_Byte space = (FT_Byte)( 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)((FT_UShort)*source++ << ( 8 - loaded )); loaded += 8; } /* now write one byte */ val = (FT_Byte)( acc >> 8 ); if ( shift ) { cur[0] |= (FT_Byte)( val >> shift ); cur[1] |= (FT_Byte)( 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 ( (FT_Int)loaded < count ) { acc |= (FT_UShort)((FT_UShort)*source++ << ( 8 - loaded )); loaded += 8; } /* now write remaining bits */ val = (FT_Byte)( ( (FT_Byte)( acc >> 8 ) ) & ~( 0xFF >> count ) ); cur[0] |= (FT_Byte)( val >> shift ); if ( count > space ) cur[1] |= (FT_Byte)( val << space ); acc <<= count; loaded -= count; } /* now, skip to next line */ if ( byte_padded ) { acc = 0; loaded = 0; /* clear accumulator on byte-padded lines */ } line_buff += line_incr; } } static const FT_Frame_Field sbit_metrics_fields[] = {#undef FT_STRUCTURE#define FT_STRUCTURE TT_SBit_MetricsRec FT_FRAME_START( 8 ), FT_FRAME_BYTE( height ), FT_FRAME_BYTE( width ), FT_FRAME_CHAR( horiBearingX ), FT_FRAME_CHAR( horiBearingY ), FT_FRAME_BYTE( horiAdvance ), FT_FRAME_CHAR( vertBearingX ), FT_FRAME_CHAR( vertBearingY ), FT_FRAME_BYTE( vertAdvance ), FT_FRAME_END }; /*************************************************************************/ /* */ /* <Function> */ /* 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> */ /* FreeType error code. 0 means success. */ /* */ static FT_Error Load_SBit_Const_Metrics( TT_SBit_Range range, FT_Stream stream ) { FT_Error error; if ( FT_READ_ULONG( range->image_size ) ) return error; return FT_STREAM_READ_FIELDS( sbit_metrics_fields, &range->metrics ); } /*************************************************************************/ /* */ /* <Function> */ /* 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> */ /* FreeType error code. 0 means success. */ /* */ static FT_Error Load_SBit_Range_Codes( TT_SBit_Range range, FT_Stream stream, FT_Bool load_offsets ) { FT_Error error; FT_ULong count, n, size; FT_Memory memory = stream->memory; if ( FT_READ_ULONG( count ) ) goto Exit; range->num_glyphs = count; /* Allocate glyph offsets table if needed */ if ( load_offsets ) { if ( FT_NEW_ARRAY( range->glyph_offsets, count ) ) goto Exit; size = count * 4L; } else size = count * 2L; /* Allocate glyph codes table and access frame */ if ( FT_NEW_ARRAY ( range->glyph_codes, count ) || FT_FRAME_ENTER( size ) ) goto Exit; for ( n = 0; n < count; n++ ) { range->glyph_codes[n] = FT_GET_USHORT(); if ( load_offsets ) range->glyph_offsets[n] = (FT_ULong)range->image_offset + FT_GET_USHORT(); } FT_FRAME_EXIT(); Exit: return error; } /*************************************************************************/ /* */ /* <Function> */ /* Load_SBit_Range */ /* */ /* <Description> */ /* Loads a given `EBLC' index/range table. */ /* */ /* <Input> */ /* range :: The target range. */ /* */ /* stream :: The input stream. */ /* */ /* <Return> */ /* FreeType error code. 0 means success. */ /* */ static FT_Error Load_SBit_Range( TT_SBit_Range range, FT_Stream stream ) { FT_Error error; FT_Memory memory = stream->memory; switch( range->index_format ) { case 1: /* variable metrics with 4-byte offsets */ case 3: /* variable metrics with 2-byte offsets */ { FT_ULong num_glyphs, n; FT_Int size_elem; FT_Bool large = FT_BOOL( range->index_format == 1 ); if ( range->last_glyph < range->first_glyph ) { error = SFNT_Err_Invalid_File_Format; goto Exit; } num_glyphs = range->last_glyph - range->first_glyph + 1L; range->num_glyphs = num_glyphs; num_glyphs++; /* XXX: BEWARE - see spec */ size_elem = large ? 4 : 2; if ( FT_NEW_ARRAY( range->glyph_offsets, num_glyphs ) || FT_FRAME_ENTER( num_glyphs * size_elem ) ) goto Exit; for ( n = 0; n < num_glyphs; n++ ) range->glyph_offsets[n] = (FT_ULong)( range->image_offset + ( large ? FT_GET_ULONG() : FT_GET_USHORT() ) ); FT_FRAME_EXIT(); } break; case 2: /* all glyphs have identical metrics */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -