You can subscribe to this list here.
| 2005 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
(92) |
Dec
(141) |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 2006 |
Jan
(126) |
Feb
(72) |
Mar
(31) |
Apr
(200) |
May
(81) |
Jun
(130) |
Jul
(112) |
Aug
(134) |
Sep
(76) |
Oct
(89) |
Nov
(153) |
Dec
(9) |
| 2007 |
Jan
(59) |
Feb
(82) |
Mar
(50) |
Apr
(20) |
May
(9) |
Jun
(81) |
Jul
(41) |
Aug
(109) |
Sep
(91) |
Oct
(87) |
Nov
(33) |
Dec
(60) |
| 2008 |
Jan
(21) |
Feb
(15) |
Mar
(38) |
Apr
(75) |
May
(59) |
Jun
(46) |
Jul
(30) |
Aug
(20) |
Sep
(35) |
Oct
(32) |
Nov
(34) |
Dec
(19) |
| 2009 |
Jan
(29) |
Feb
(71) |
Mar
(54) |
Apr
(17) |
May
(4) |
Jun
|
Jul
(3) |
Aug
|
Sep
|
Oct
|
Nov
|
Dec
(3) |
| 2010 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
(3) |
Aug
(58) |
Sep
(7) |
Oct
(7) |
Nov
(12) |
Dec
(18) |
| 2011 |
Jan
(17) |
Feb
(29) |
Mar
(11) |
Apr
(5) |
May
(1) |
Jun
|
Jul
|
Aug
(11) |
Sep
|
Oct
|
Nov
|
Dec
|
| 2012 |
Jan
(2) |
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
| 2014 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
(87) |
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
| 2015 |
Jan
|
Feb
|
Mar
|
Apr
|
May
(44) |
Jun
(79) |
Jul
(16) |
Aug
(31) |
Sep
|
Oct
(51) |
Nov
|
Dec
|
| 2016 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
(2) |
Oct
|
Nov
|
Dec
|
|
From: Ehud S. <esh...@us...> - 2006-04-21 16:22:39
|
Update of /cvsroot/roadmap/roadmap_editor/src/freetype/src/cid In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv22848/src/cid Added Files: cidgload.c cidload.c cidobjs.c cidparse.c cidriver.c type1cid.c Log Message: Import freetype sources. --- NEW FILE: cidload.c --- /***************************************************************************/ /* */ /* cidload.c */ /* */ /* CID-keyed Type1 font loader (body). */ /* */ /* Copyright 1996-2001, 2002, 2003, 2004, 2005 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_CONFIG_CONFIG_H #include FT_MULTIPLE_MASTERS_H #include FT_INTERNAL_TYPE1_TYPES_H #include "cidload.h" #include "ciderrs.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_cidload /* read a single offset */ FT_LOCAL_DEF( FT_Long ) cid_get_offset( FT_Byte* *start, FT_Byte offsize ) { FT_Long result; FT_Byte* p = *start; for ( result = 0; offsize > 0; offsize-- ) { result <<= 8; result |= *p++; } *start = p; return result; } /*************************************************************************/ /*************************************************************************/ /***** *****/ /***** TYPE 1 SYMBOL PARSING *****/ /***** *****/ /*************************************************************************/ /*************************************************************************/ static FT_Error cid_load_keyword( CID_Face face, CID_Loader* loader, const T1_Field keyword ) { FT_Error error; CID_Parser* parser = &loader->parser; FT_Byte* object; void* dummy_object; CID_FaceInfo cid = &face->cid; /* if the keyword has a dedicated callback, call it */ if ( keyword->type == T1_FIELD_TYPE_CALLBACK ) { keyword->reader( (FT_Face)face, parser ); error = parser->root.error; goto Exit; } /* we must now compute the address of our target object */ switch ( keyword->location ) { case T1_FIELD_LOCATION_CID_INFO: object = (FT_Byte*)cid; break; case T1_FIELD_LOCATION_FONT_INFO: object = (FT_Byte*)&cid->font_info; break; case T1_FIELD_LOCATION_BBOX: object = (FT_Byte*)&cid->font_bbox; break; default: { CID_FaceDict dict; if ( parser->num_dict < 0 ) { FT_ERROR(( "cid_load_keyword: invalid use of `%s'!\n", keyword->ident )); error = CID_Err_Syntax_Error; goto Exit; } dict = cid->font_dicts + parser->num_dict; switch ( keyword->location ) { case T1_FIELD_LOCATION_PRIVATE: object = (FT_Byte*)&dict->private_dict; break; default: object = (FT_Byte*)dict; } } } dummy_object = object; /* now, load the keyword data in the object's field(s) */ if ( keyword->type == T1_FIELD_TYPE_INTEGER_ARRAY || keyword->type == T1_FIELD_TYPE_FIXED_ARRAY ) error = cid_parser_load_field_table( &loader->parser, keyword, &dummy_object ); else error = cid_parser_load_field( &loader->parser, keyword, &dummy_object ); Exit: return error; } FT_CALLBACK_DEF( FT_Error ) parse_font_matrix( CID_Face face, CID_Parser* parser ) { FT_Matrix* matrix; FT_Vector* offset; CID_FaceDict dict; FT_Face root = (FT_Face)&face->root; FT_Fixed temp[6]; FT_Fixed temp_scale; if ( parser->num_dict >= 0 ) { dict = face->cid.font_dicts + parser->num_dict; matrix = &dict->font_matrix; offset = &dict->font_offset; (void)cid_parser_to_fixed_array( parser, 6, temp, 3 ); temp_scale = FT_ABS( temp[3] ); /* Set units per EM based on FontMatrix values. We set the value to */ /* `1000/temp_scale', because temp_scale was already multiplied by */ /* 1000 (in `t1_tofixed', from psobjs.c). */ root->units_per_EM = (FT_UShort)( FT_DivFix( 0x10000L, FT_DivFix( temp_scale, 1000 ) ) ); /* we need to scale the values by 1.0/temp[3] */ if ( temp_scale != 0x10000L ) { temp[0] = FT_DivFix( temp[0], temp_scale ); temp[1] = FT_DivFix( temp[1], temp_scale ); temp[2] = FT_DivFix( temp[2], temp_scale ); temp[4] = FT_DivFix( temp[4], temp_scale ); temp[5] = FT_DivFix( temp[5], temp_scale ); temp[3] = 0x10000L; } matrix->xx = temp[0]; matrix->yx = temp[1]; matrix->xy = temp[2]; matrix->yy = temp[3]; /* note that the font offsets are expressed in integer font units */ offset->x = temp[4] >> 16; offset->y = temp[5] >> 16; } return CID_Err_Ok; /* this is a callback function; */ /* we must return an error code */ } FT_CALLBACK_DEF( FT_Error ) parse_fd_array( CID_Face face, CID_Parser* parser ) { CID_FaceInfo cid = &face->cid; FT_Memory memory = face->root.memory; FT_Error error = CID_Err_Ok; FT_Long num_dicts; num_dicts = cid_parser_to_int( parser ); if ( !cid->font_dicts ) { FT_Int n; if ( FT_NEW_ARRAY( cid->font_dicts, num_dicts ) ) goto Exit; cid->num_dicts = (FT_UInt)num_dicts; /* don't forget to set a few defaults */ for ( n = 0; n < cid->num_dicts; n++ ) { CID_FaceDict dict = cid->font_dicts + n; /* default value for lenIV */ dict->private_dict.lenIV = 4; } } Exit: return error; } static const T1_FieldRec cid_field_records[] = { #include "cidtoken.h" T1_FIELD_CALLBACK( "FDArray", parse_fd_array ) T1_FIELD_CALLBACK( "FontMatrix", parse_font_matrix ) { 0, T1_FIELD_LOCATION_CID_INFO, T1_FIELD_TYPE_NONE, 0, 0, 0, 0, 0 } }; static FT_Error cid_parse_dict( CID_Face face, CID_Loader* loader, FT_Byte* base, FT_Long size ) { CID_Parser* parser = &loader->parser; parser->root.cursor = base; parser->root.limit = base + size; parser->root.error = CID_Err_Ok; { FT_Byte* cur = base; FT_Byte* limit = cur + size; for (;;) { FT_Byte* newlimit; parser->root.cursor = cur; cid_parser_skip_spaces( parser ); if ( parser->root.cursor >= limit ) newlimit = limit - 1 - 17; else newlimit = parser->root.cursor - 17; /* look for `%ADOBeginFontDict' */ for ( ; cur < newlimit; cur++ ) { if ( *cur == '%' && ft_strncmp( (char*)cur, "%ADOBeginFontDict", 17 ) == 0 ) { /* if /FDArray was found, then cid->num_dicts is > 0, and */ /* we can start increasing parser->num_dict */ if ( face->cid.num_dicts > 0 ) parser->num_dict++; } } cur = parser->root.cursor; /* no error can occur in cid_parser_skip_spaces */ if ( cur >= limit ) break; cid_parser_skip_PS_token( parser ); if ( parser->root.cursor >= limit || parser->root.error ) break; /* look for immediates */ if ( *cur == '/' && cur + 2 < limit ) { FT_PtrDist len; cur++; len = parser->root.cursor - cur; if ( len > 0 && len < 22 ) { /* now compare the immediate name to the keyword table */ T1_Field keyword = (T1_Field)cid_field_records; for (;;) { FT_Byte* name; name = (FT_Byte*)keyword->ident; if ( !name ) break; if ( cur[0] == name[0] && len == (FT_PtrDist)ft_strlen( (const char*)name ) ) { FT_PtrDist n; for ( n = 1; n < len; n++ ) if ( cur[n] != name[n] ) break; if ( n >= len ) { /* we found it - run the parsing callback */ parser->root.error = cid_load_keyword( face, loader, keyword ); if ( parser->root.error ) return parser->root.error; break; } } keyword++; } } } cur = parser->root.cursor; } } return parser->root.error; } /* read the subrmap and the subrs of each font dict */ static FT_Error cid_read_subrs( CID_Face face ) { CID_FaceInfo cid = &face->cid; FT_Memory memory = face->root.memory; FT_Stream stream = face->cid_stream; FT_Error error; FT_Int n; CID_Subrs subr; FT_UInt max_offsets = 0; FT_ULong* offsets = 0; PSAux_Service psaux = (PSAux_Service)face->psaux; if ( FT_NEW_ARRAY( face->subrs, cid->num_dicts ) ) goto Exit; subr = face->subrs; for ( n = 0; n < cid->num_dicts; n++, subr++ ) { CID_FaceDict dict = cid->font_dicts + n; FT_Int lenIV = dict->private_dict.lenIV; FT_UInt count, num_subrs = dict->num_subrs; FT_ULong data_len; FT_Byte* p; /* reallocate offsets array if needed */ if ( num_subrs + 1 > max_offsets ) { FT_UInt new_max = FT_PAD_CEIL( num_subrs + 1, 4 ); if ( FT_RENEW_ARRAY( offsets, max_offsets, new_max ) ) goto Fail; max_offsets = new_max; } /* read the subrmap's offsets */ if ( FT_STREAM_SEEK( cid->data_offset + dict->subrmap_offset ) || FT_FRAME_ENTER( ( num_subrs + 1 ) * dict->sd_bytes ) ) goto Fail; p = (FT_Byte*)stream->cursor; for ( count = 0; count <= num_subrs; count++ ) offsets[count] = cid_get_offset( &p, (FT_Byte)dict->sd_bytes ); FT_FRAME_EXIT(); /* now, compute the size of subrs charstrings, */ /* allocate, and read them */ data_len = offsets[num_subrs] - offsets[0]; if ( FT_NEW_ARRAY( subr->code, num_subrs + 1 ) || FT_ALLOC( subr->code[0], data_len ) ) goto Fail; if ( FT_STREAM_SEEK( cid->data_offset + offsets[0] ) || FT_STREAM_READ( subr->code[0], data_len ) ) goto Fail; /* set up pointers */ for ( count = 1; count <= num_subrs; count++ ) { FT_ULong len; len = offsets[count] - offsets[count - 1]; subr->code[count] = subr->code[count - 1] + len; } /* decrypt subroutines, but only if lenIV >= 0 */ if ( lenIV >= 0 ) { for ( count = 0; count < num_subrs; count++ ) { FT_ULong len; len = offsets[count + 1] - offsets[count]; psaux->t1_decrypt( subr->code[count], len, 4330 ); } } subr->num_subrs = num_subrs; } Exit: FT_FREE( offsets ); return error; Fail: if ( face->subrs ) { for ( n = 0; n < cid->num_dicts; n++ ) { if ( face->subrs[n].code ) FT_FREE( face->subrs[n].code[0] ); FT_FREE( face->subrs[n].code ); } FT_FREE( face->subrs ); } goto Exit; } static void t1_init_loader( CID_Loader* loader, CID_Face face ) { FT_UNUSED( face ); FT_MEM_ZERO( loader, sizeof ( *loader ) ); } static void t1_done_loader( CID_Loader* loader ) { CID_Parser* parser = &loader->parser; /* finalize parser */ cid_parser_done( parser ); } static FT_Error cid_hex_to_binary( FT_Byte* data, FT_Long data_len, FT_ULong offset, CID_Face face ) { FT_Stream stream = face->root.stream; FT_Error error; FT_Byte buffer[256]; FT_Byte *p, *plimit; FT_Byte *d, *dlimit; FT_Byte val; FT_Bool upper_nibble, done; if ( FT_STREAM_SEEK( offset ) ) goto Exit; d = data; dlimit = d + data_len; p = buffer; plimit = p; upper_nibble = 1; done = 0; while ( d < dlimit ) { if ( p >= plimit ) { FT_ULong oldpos = FT_STREAM_POS(); FT_ULong size = stream->size - oldpos; if ( size == 0 ) { error = CID_Err_Syntax_Error; goto Exit; } if ( FT_STREAM_READ( buffer, 256 > size ? size : 256 ) ) goto Exit; p = buffer; plimit = p + FT_STREAM_POS() - oldpos; } if ( ft_isdigit( *p ) ) val = (FT_Byte)( *p - '0' ); else if ( *p >= 'a' && *p <= 'f' ) val = (FT_Byte)( *p - 'a' ); else if ( *p >= 'A' && *p <= 'F' ) val = (FT_Byte)( *p - 'A' + 10 ); else if ( *p == ' ' || *p == '\t' || *p == '\r' || *p == '\n' || *p == '\f' || *p == '\0' ) { p++; continue; } else if ( *p == '>' ) { val = 0; done = 1; } else { error = CID_Err_Syntax_Error; goto Exit; } if ( upper_nibble ) *d = (FT_Byte)( val << 4 ); else { *d = (FT_Byte)( *d + val ); d++; } upper_nibble = (FT_Byte)( 1 - upper_nibble ); if ( done ) break; p++; } error = CID_Err_Ok; Exit: return error; } FT_LOCAL_DEF( FT_Error ) cid_face_open( CID_Face face, FT_Int face_index ) { CID_Loader loader; CID_Parser* parser; FT_Memory memory = face->root.memory; FT_Error error; t1_init_loader( &loader, face ); parser = &loader.parser; error = cid_parser_new( parser, face->root.stream, face->root.memory, (PSAux_Service)face->psaux ); if ( error ) goto Exit; error = cid_parse_dict( face, &loader, parser->postscript, parser->postscript_len ); if ( error ) goto Exit; if ( face_index < 0 ) goto Exit; if ( FT_NEW( face->cid_stream ) ) goto Exit; if ( parser->binary_length ) { /* we must convert the data section from hexadecimal to binary */ if ( FT_ALLOC( face->binary_data, parser->binary_length ) || cid_hex_to_binary( face->binary_data, parser->binary_length, parser->data_offset, face ) ) goto Exit; FT_Stream_OpenMemory( face->cid_stream, face->binary_data, parser->binary_length ); face->cid.data_offset = 0; } else { *face->cid_stream = *face->root.stream; face->cid.data_offset = loader.parser.data_offset; } error = cid_read_subrs( face ); Exit: t1_done_loader( &loader ); return error; } /* END */ --- NEW FILE: cidgload.c --- /***************************************************************************/ /* */ /* cidgload.c */ /* */ /* CID-keyed Type1 Glyph Loader (body). */ /* */ /* Copyright 1996-2001, 2002, 2003, 2004 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 "cidload.h" #include "cidgload.h" #include FT_INTERNAL_DEBUG_H #include FT_INTERNAL_STREAM_H #include FT_OUTLINE_H #include "ciderrs.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_cidgload FT_CALLBACK_DEF( FT_Error ) cid_load_glyph( T1_Decoder decoder, FT_UInt glyph_index ) { CID_Face face = (CID_Face)decoder->builder.face; CID_FaceInfo cid = &face->cid; FT_Byte* p; FT_UInt fd_select; FT_Stream stream = face->cid_stream; FT_Error error = 0; FT_Byte* charstring = 0; FT_Memory memory = face->root.memory; FT_ULong glyph_length = 0; PSAux_Service psaux = (PSAux_Service)face->psaux; #ifdef FT_CONFIG_OPTION_INCREMENTAL /* For incremental fonts get the character data using */ /* the callback function. */ if ( face->root.internal->incremental_interface ) { FT_Data glyph_data; error = face->root.internal->incremental_interface->funcs->get_glyph_data( face->root.internal->incremental_interface->object, glyph_index, &glyph_data ); if ( error ) goto Exit; p = (FT_Byte*)glyph_data.pointer; fd_select = (FT_UInt)cid_get_offset( &p, (FT_Byte)cid->fd_bytes ); if ( glyph_data.length != 0 ) { glyph_length = glyph_data.length - cid->fd_bytes; FT_ALLOC( charstring, glyph_length ); if ( !error ) ft_memcpy( charstring, glyph_data.pointer + cid->fd_bytes, glyph_length ); } face->root.internal->incremental_interface->funcs->free_glyph_data( face->root.internal->incremental_interface->object, &glyph_data ); if ( error ) goto Exit; } else #endif /* FT_CONFIG_OPTION_INCREMENTAL */ /* For ordinary fonts read the CID font dictionary index */ /* and charstring offset from the CIDMap. */ { FT_UInt entry_len = cid->fd_bytes + cid->gd_bytes; FT_ULong off1; if ( FT_STREAM_SEEK( cid->data_offset + cid->cidmap_offset + glyph_index * entry_len ) || FT_FRAME_ENTER( 2 * entry_len ) ) goto Exit; p = (FT_Byte*)stream->cursor; fd_select = (FT_UInt) cid_get_offset( &p, (FT_Byte)cid->fd_bytes ); off1 = (FT_ULong)cid_get_offset( &p, (FT_Byte)cid->gd_bytes ); p += cid->fd_bytes; glyph_length = cid_get_offset( &p, (FT_Byte)cid->gd_bytes ) - off1; FT_FRAME_EXIT(); if ( glyph_length == 0 ) goto Exit; if ( FT_ALLOC( charstring, glyph_length ) ) goto Exit; if ( FT_STREAM_READ_AT( cid->data_offset + off1, charstring, glyph_length ) ) goto Exit; } /* Now set up the subrs array and parse the charstrings. */ { CID_FaceDict dict; CID_Subrs cid_subrs = face->subrs + fd_select; FT_Int cs_offset; /* Set up subrs */ decoder->num_subrs = cid_subrs->num_subrs; decoder->subrs = cid_subrs->code; decoder->subrs_len = 0; /* Set up font matrix */ dict = cid->font_dicts + fd_select; decoder->font_matrix = dict->font_matrix; decoder->font_offset = dict->font_offset; decoder->lenIV = dict->private_dict.lenIV; /* Decode the charstring. */ /* Adjustment for seed bytes. */ cs_offset = ( decoder->lenIV >= 0 ? decoder->lenIV : 0 ); /* Decrypt only if lenIV >= 0. */ if ( decoder->lenIV >= 0 ) psaux->t1_decrypt( charstring, glyph_length, 4330 ); error = decoder->funcs.parse_charstrings( decoder, charstring + cs_offset, (FT_Int)glyph_length - cs_offset ); } FT_FREE( charstring ); #ifdef FT_CONFIG_OPTION_INCREMENTAL /* Incremental fonts can optionally override the metrics. */ if ( !error && face->root.internal->incremental_interface && face->root.internal->incremental_interface->funcs->get_glyph_metrics ) { FT_Incremental_MetricsRec metrics; metrics.bearing_x = decoder->builder.left_bearing.x; metrics.bearing_y = decoder->builder.left_bearing.y; metrics.advance = decoder->builder.advance.x; error = face->root.internal->incremental_interface->funcs->get_glyph_metrics( face->root.internal->incremental_interface->object, glyph_index, FALSE, &metrics ); decoder->builder.left_bearing.x = metrics.bearing_x; decoder->builder.left_bearing.y = metrics.bearing_y; decoder->builder.advance.x = metrics.advance; decoder->builder.advance.y = 0; } #endif /* FT_CONFIG_OPTION_INCREMENTAL */ Exit: return error; } #if 0 /*************************************************************************/ /*************************************************************************/ /*************************************************************************/ /********** *********/ /********** *********/ /********** COMPUTE THE MAXIMUM ADVANCE WIDTH *********/ /********** *********/ /********** The following code is in charge of computing *********/ /********** the maximum advance width of the font. It *********/ /********** quickly processes each glyph charstring to *********/ /********** extract the value from either a `sbw' or `seac' *********/ /********** operator. *********/ /********** *********/ /*************************************************************************/ /*************************************************************************/ /*************************************************************************/ FT_LOCAL_DEF( FT_Error ) cid_face_compute_max_advance( CID_Face face, FT_Int* max_advance ) { FT_Error error; T1_DecoderRec decoder; FT_Int glyph_index; PSAux_Service psaux = (PSAux_Service)face->psaux; *max_advance = 0; /* Initialize load decoder */ error = psaux->t1_decoder_funcs->init( &decoder, (FT_Face)face, 0, /* size */ 0, /* glyph slot */ 0, /* glyph names! XXX */ 0, /* blend == 0 */ 0, /* hinting == 0 */ cid_load_glyph ); if ( error ) return error; decoder.builder.metrics_only = 1; decoder.builder.load_points = 0; /* for each glyph, parse the glyph charstring and extract */ /* the advance width */ for ( glyph_index = 0; glyph_index < face->root.num_glyphs; glyph_index++ ) { /* now get load the unscaled outline */ error = cid_load_glyph( &decoder, glyph_index ); /* ignore the error if one occurred - skip to next glyph */ } *max_advance = decoder.builder.advance.x; return CID_Err_Ok; } #endif /* 0 */ /*************************************************************************/ /*************************************************************************/ /*************************************************************************/ /********** *********/ /********** *********/ /********** UNHINTED GLYPH LOADER *********/ /********** *********/ /********** The following code is in charge of loading a *********/ /********** single outline. It completely ignores hinting *********/ /********** and is used when FT_LOAD_NO_HINTING is set. *********/ /********** *********/ /*************************************************************************/ /*************************************************************************/ /*************************************************************************/ FT_LOCAL_DEF( FT_Error ) cid_slot_load_glyph( FT_GlyphSlot cidglyph, /* CID_GlyphSlot */ FT_Size cidsize, /* CID_Size */ FT_UInt glyph_index, FT_Int32 load_flags ) { CID_GlyphSlot glyph = (CID_GlyphSlot)cidglyph; CID_Size size = (CID_Size)cidsize; FT_Error error; T1_DecoderRec decoder; CID_Face face = (CID_Face)cidglyph->face; FT_Bool hinting; PSAux_Service psaux = (PSAux_Service)face->psaux; FT_Matrix font_matrix; FT_Vector font_offset; if ( load_flags & FT_LOAD_NO_RECURSE ) load_flags |= FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING; glyph->x_scale = cidsize->metrics.x_scale; glyph->y_scale = cidsize->metrics.y_scale; cidglyph->outline.n_points = 0; cidglyph->outline.n_contours = 0; hinting = FT_BOOL( ( load_flags & FT_LOAD_NO_SCALE ) == 0 && ( load_flags & FT_LOAD_NO_HINTING ) == 0 ); cidglyph->format = FT_GLYPH_FORMAT_OUTLINE; { error = psaux->t1_decoder_funcs->init( &decoder, cidglyph->face, cidsize, cidglyph, 0, /* glyph names -- XXX */ 0, /* blend == 0 */ hinting, FT_LOAD_TARGET_MODE( load_flags ), cid_load_glyph ); /* set up the decoder */ decoder.builder.no_recurse = FT_BOOL( ( ( load_flags & FT_LOAD_NO_RECURSE ) != 0 ) ); error = cid_load_glyph( &decoder, glyph_index ); font_matrix = decoder.font_matrix; font_offset = decoder.font_offset; /* save new glyph tables */ psaux->t1_decoder_funcs->done( &decoder ); } /* now, set the metrics -- this is rather simple, as */ /* the left side bearing is the xMin, and the top side */ /* bearing the yMax */ if ( !error ) { cidglyph->outline.flags &= FT_OUTLINE_OWNER; cidglyph->outline.flags |= FT_OUTLINE_REVERSE_FILL; /* for composite glyphs, return only left side bearing and */ /* advance width */ if ( load_flags & FT_LOAD_NO_RECURSE ) { FT_Slot_Internal internal = cidglyph->internal; cidglyph->metrics.horiBearingX = decoder.builder.left_bearing.x; cidglyph->metrics.horiAdvance = decoder.builder.advance.x; internal->glyph_matrix = font_matrix; internal->glyph_delta = font_offset; internal->glyph_transformed = 1; } else { FT_BBox cbox; FT_Glyph_Metrics* metrics = &cidglyph->metrics; FT_Vector advance; /* copy the _unscaled_ advance width */ metrics->horiAdvance = decoder.builder.advance.x; cidglyph->linearHoriAdvance = decoder.builder.advance.x; cidglyph->internal->glyph_transformed = 0; /* make up vertical metrics */ metrics->vertBearingX = 0; metrics->vertBearingY = 0; metrics->vertAdvance = 0; cidglyph->linearVertAdvance = 0; cidglyph->format = FT_GLYPH_FORMAT_OUTLINE; if ( size && cidsize->metrics.y_ppem < 24 ) cidglyph->outline.flags |= FT_OUTLINE_HIGH_PRECISION; /* apply the font matrix */ FT_Outline_Transform( &cidglyph->outline, &font_matrix ); FT_Outline_Translate( &cidglyph->outline, font_offset.x, font_offset.y ); advance.x = metrics->horiAdvance; advance.y = 0; FT_Vector_Transform( &advance, &font_matrix ); metrics->horiAdvance = advance.x + font_offset.x; advance.x = 0; advance.y = metrics->vertAdvance; FT_Vector_Transform( &advance, &font_matrix ); metrics->vertAdvance = advance.y + font_offset.y; if ( ( load_flags & FT_LOAD_NO_SCALE ) == 0 ) { /* scale the outline and the metrics */ FT_Int n; FT_Outline* cur = decoder.builder.base; FT_Vector* vec = cur->points; FT_Fixed x_scale = glyph->x_scale; FT_Fixed y_scale = glyph->y_scale; /* First of all, scale the points */ if ( !hinting ) for ( n = cur->n_points; n > 0; n--, vec++ ) { vec->x = FT_MulFix( vec->x, x_scale ); vec->y = FT_MulFix( vec->y, y_scale ); } FT_Outline_Get_CBox( &cidglyph->outline, &cbox ); /* Then scale the metrics */ metrics->horiAdvance = FT_MulFix( metrics->horiAdvance, x_scale ); metrics->vertAdvance = FT_MulFix( metrics->vertAdvance, y_scale ); metrics->vertBearingX = FT_MulFix( metrics->vertBearingX, x_scale ); metrics->vertBearingY = FT_MulFix( metrics->vertBearingY, y_scale ); if ( hinting ) { metrics->horiAdvance = FT_PIX_ROUND( metrics->horiAdvance ); metrics->vertAdvance = FT_PIX_ROUND( metrics->vertAdvance ); metrics->vertBearingX = FT_PIX_ROUND( metrics->vertBearingX ); metrics->vertBearingY = FT_PIX_ROUND( metrics->vertBearingY ); } } /* compute the other metrics */ FT_Outline_Get_CBox( &cidglyph->outline, &cbox ); /* grid fit the bounding box if necessary */ if ( hinting ) { cbox.xMin = FT_PIX_FLOOR( cbox.xMin ); cbox.yMin = FT_PIX_FLOOR( cbox.yMin ); cbox.xMax = FT_PIX_CEIL( cbox.xMax ); cbox.yMax = FT_PIX_CEIL( cbox.yMax ); } metrics->width = cbox.xMax - cbox.xMin; metrics->height = cbox.yMax - cbox.yMin; metrics->horiBearingX = cbox.xMin; metrics->horiBearingY = cbox.yMax; } } return error; } /* END */ --- NEW FILE: cidobjs.c --- /***************************************************************************/ /* */ /* cidobjs.c */ /* */ /* CID objects manager (body). */ /* */ /* Copyright 1996-2001, 2002, 2003, 2004, 2005 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 "cidgload.h" #include "cidload.h" #include FT_SERVICE_POSTSCRIPT_CMAPS_H #include FT_INTERNAL_POSTSCRIPT_AUX_H #include FT_INTERNAL_POSTSCRIPT_HINTS_H #include "ciderrs.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_cidobjs /*************************************************************************/ /* */ /* SLOT FUNCTIONS */ /* */ /*************************************************************************/ FT_LOCAL_DEF( void ) cid_slot_done( FT_GlyphSlot slot ) { slot->internal->glyph_hints = 0; } FT_LOCAL_DEF( FT_Error ) cid_slot_init( FT_GlyphSlot slot ) { CID_Face face; PSHinter_Service pshinter; face = (CID_Face)slot->face; pshinter = (PSHinter_Service)face->pshinter; if ( pshinter ) { FT_Module module; module = FT_Get_Module( slot->face->driver->root.library, "pshinter" ); if ( module ) { T1_Hints_Funcs funcs; funcs = pshinter->get_t1_funcs( module ); slot->internal->glyph_hints = (void*)funcs; } } return 0; } /*************************************************************************/ /* */ /* SIZE FUNCTIONS */ /* */ /*************************************************************************/ static PSH_Globals_Funcs cid_size_get_globals_funcs( CID_Size size ) { CID_Face face = (CID_Face)size->root.face; PSHinter_Service pshinter = (PSHinter_Service)face->pshinter; FT_Module module; module = FT_Get_Module( size->root.face->driver->root.library, "pshinter" ); return ( module && pshinter && pshinter->get_globals_funcs ) ? pshinter->get_globals_funcs( module ) : 0; } FT_LOCAL_DEF( void ) cid_size_done( FT_Size cidsize ) /* CID_Size */ { CID_Size size = (CID_Size)cidsize; if ( cidsize->internal ) { PSH_Globals_Funcs funcs; funcs = cid_size_get_globals_funcs( size ); if ( funcs ) funcs->destroy( (PSH_Globals)cidsize->internal ); cidsize->internal = 0; } } FT_LOCAL_DEF( FT_Error ) cid_size_init( FT_Size cidsize ) /* CID_Size */ { CID_Size size = (CID_Size)cidsize; FT_Error error = 0; PSH_Globals_Funcs funcs = cid_size_get_globals_funcs( size ); if ( funcs ) { PSH_Globals globals; CID_Face face = (CID_Face)cidsize->face; CID_FaceDict dict = face->cid.font_dicts + face->root.face_index; PS_Private priv = &dict->private_dict; error = funcs->create( cidsize->face->memory, priv, &globals ); if ( !error ) cidsize->internal = (FT_Size_Internal)(void*)globals; } return error; } FT_LOCAL_DEF( FT_Error ) cid_size_reset( FT_Size cidsize, /* CID_Size */ FT_UInt char_width, FT_UInt char_height ) { CID_Size size = (CID_Size)cidsize; PSH_Globals_Funcs funcs = cid_size_get_globals_funcs( size ); FT_Error error = 0; FT_UNUSED( char_width ); FT_UNUSED( char_height ); if ( funcs ) error = funcs->set_scale( (PSH_Globals)cidsize->internal, cidsize->metrics.x_scale, cidsize->metrics.y_scale, 0, 0 ); return error; } FT_LOCAL_DEF( FT_Error ) cid_point_size_reset( FT_Size size, FT_F26Dot6 char_width, FT_F26Dot6 char_height, FT_UInt horz_resolution, FT_UInt vert_resolution ) { FT_UNUSED( char_width ); FT_UNUSED( char_height ); FT_UNUSED( horz_resolution ); FT_UNUSED( vert_resolution ); return cid_size_reset( size, 0, 0 ); } /*************************************************************************/ /* */ /* FACE FUNCTIONS */ /* */ /*************************************************************************/ /*************************************************************************/ /* */ /* <Function> */ /* cid_face_done */ /* */ /* <Description> */ /* Finalizes a given face object. */ /* */ /* <Input> */ /* face :: A pointer to the face object to destroy. */ /* */ FT_LOCAL_DEF( void ) cid_face_done( FT_Face cidface ) /* CID_Face */ { CID_Face face = (CID_Face)cidface; FT_Memory memory; if ( face ) { CID_FaceInfo cid = &face->cid; PS_FontInfo info = &cid->font_info; memory = cidface->memory; /* release subrs */ if ( face->subrs ) { FT_Int n; for ( n = 0; n < cid->num_dicts; n++ ) { CID_Subrs subr = face->subrs + n; if ( subr->code ) { FT_FREE( subr->code[0] ); FT_FREE( subr->code ); } } FT_FREE( face->subrs ); } /* release FontInfo strings */ FT_FREE( info->version ); FT_FREE( info->notice ); FT_FREE( info->full_name ); FT_FREE( info->family_name ); FT_FREE( info->weight ); /* release font dictionaries */ FT_FREE( cid->font_dicts ); cid->num_dicts = 0; /* release other strings */ FT_FREE( cid->cid_font_name ); FT_FREE( cid->registry ); FT_FREE( cid->ordering ); cidface->family_name = 0; cidface->style_name = 0; FT_FREE( face->binary_data ); FT_FREE( face->cid_stream ); } } /*************************************************************************/ /* */ /* <Function> */ /* cid_face_init */ /* */ /* <Description> */ /* Initializes a given CID face object. */ /* */ /* <Input> */ /* stream :: The source font stream. */ /* */ /* face_index :: The index of the font face in the resource. */ /* */ /* num_params :: Number of additional generic parameters. Ignored. */ /* */ /* params :: Additional generic parameters. Ignored. */ /* */ /* <InOut> */ /* face :: The newly built face object. */ /* */ /* <Return> */ /* FreeType error code. 0 means success. */ /* */ FT_LOCAL_DEF( FT_Error ) cid_face_init( FT_Stream stream, FT_Face cidface, /* CID_Face */ FT_Int face_index, FT_Int num_params, FT_Parameter* params ) { CID_Face face = (CID_Face)cidface; FT_Error error; PSAux_Service psaux; PSHinter_Service pshinter; FT_UNUSED( num_params ); FT_UNUSED( params ); FT_UNUSED( stream ); cidface->num_faces = 1; psaux = (PSAux_Service)face->psaux; if ( !psaux ) { psaux = (PSAux_Service)FT_Get_Module_Interface( FT_FACE_LIBRARY( face ), "psaux" ); face->psaux = psaux; } pshinter = (PSHinter_Service)face->pshinter; if ( !pshinter ) { pshinter = (PSHinter_Service)FT_Get_Module_Interface( FT_FACE_LIBRARY( face ), "pshinter" ); face->pshinter = pshinter; } /* open the tokenizer; this will also check the font format */ if ( FT_STREAM_SEEK( 0 ) ) goto Exit; error = cid_face_open( face, face_index ); if ( error ) goto Exit; /* if we just wanted to check the format, leave successfully now */ if ( face_index < 0 ) goto Exit; /* check the face index */ if ( face_index != 0 ) { FT_ERROR(( "cid_face_init: invalid face index\n" )); error = CID_Err_Invalid_Argument; goto Exit; } /* now load the font program into the face object */ /* initialize the face object fields */ /* set up root face fields */ { CID_FaceInfo cid = &face->cid; PS_FontInfo info = &cid->font_info; cidface->num_glyphs = cid->cid_count; cidface->num_charmaps = 0; cidface->face_index = face_index; cidface->face_flags = FT_FACE_FLAG_SCALABLE; cidface->face_flags |= FT_FACE_FLAG_HORIZONTAL; if ( info->is_fixed_pitch ) cidface->face_flags |= FT_FACE_FLAG_FIXED_WIDTH; /* XXX: TODO: add kerning with .afm support */ /* get style name -- be careful, some broken fonts only */ /* have a /FontName dictionary entry! */ cidface->family_name = info->family_name; /* assume "Regular" style if we don't know better */ cidface->style_name = (char *)"Regular"; if ( cidface->family_name ) { char* full = info->full_name; char* family = cidface->family_name; if ( full ) { while ( *full ) { if ( *full == *family ) { family++; full++; } else { if ( *full == ' ' || *full == '-' ) full++; else if ( *family == ' ' || *family == '-' ) family++; else { if ( !*family ) cidface->style_name = full; break; } } } } } else { /* do we have a `/FontName'? */ if ( cid->cid_font_name ) cidface->family_name = cid->cid_font_name; } /* compute style flags */ cidface->style_flags = 0; if ( info->italic_angle ) cidface->style_flags |= FT_STYLE_FLAG_ITALIC; if ( info->weight ) { if ( !ft_strcmp( info->weight, "Bold" ) || !ft_strcmp( info->weight, "Black" ) ) cidface->style_flags |= FT_STYLE_FLAG_BOLD; } /* no embedded bitmap support */ cidface->num_fixed_sizes = 0; cidface->available_sizes = 0; cidface->bbox.xMin = cid->font_bbox.xMin >> 16; cidface->bbox.yMin = cid->font_bbox.yMin >> 16; cidface->bbox.xMax = ( cid->font_bbox.xMax + 0xFFFFU ) >> 16; cidface->bbox.yMax = ( cid->font_bbox.yMax + 0xFFFFU ) >> 16; if ( !cidface->units_per_EM ) cidface->units_per_EM = 1000; cidface->ascender = (FT_Short)( cidface->bbox.yMax ); cidface->descender = (FT_Short)( cidface->bbox.yMin ); cidface->height = (FT_Short)( ( ( cidface->ascender - cidface->descender ) * 12 ) / 10 ); cidface->underline_position = (FT_Short)info->underline_position; cidface->underline_thickness = (FT_Short)info->underline_thickness; cidface->internal->max_points = 0; cidface->internal->max_contours = 0; } Exit: return error; } /*************************************************************************/ /* */ /* <Function> */ /* cid_driver_init */ /* */ /* <Description> */ /* Initializes a given CID driver object. */ /* */ /* <Input> */ /* driver :: A handle to the target driver object. */ /* */ /* <Return> */ /* FreeType error code. 0 means success. */ /* */ FT_LOCAL_DEF( FT_Error ) cid_driver_init( FT_Module driver ) { FT_UNUSED( driver ); return CID_Err_Ok; } /*************************************************************************/ /* */ /* <Function> */ /* cid_driver_done */ /* */ /* <Description> */ /* Finalizes a given CID driver. */ /* */ /* <Input> */ /* driver :: A handle to the target CID driver. */ /* */ FT_LOCAL_DEF( void ) cid_driver_done( FT_Module driver ) { FT_UNUSED( driver ); } /* END */ --- NEW FILE: cidparse.c --- /***************************************************************************/ /* */ /* cidparse.c */ /* */ /* CID-keyed Type1 parser (body). */ /* */ /* Copyright 1996-2001, 2002, 2003, 2004, 2005 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_CALC_H #include FT_INTERNAL_OBJECTS_H #include FT_INTERNAL_STREAM_H #include "cidparse.h" #include "ciderrs.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_cidparse /*************************************************************************/ /*************************************************************************/ /*************************************************************************/ /***** *****/ /***** INPUT STREAM PARSER *****/ /***** *****/ /*************************************************************************/ /*************************************************************************/ /*************************************************************************/ FT_LOCAL_DEF( FT_Error ) cid_parser_new( CID_Parser* parser, FT_Stream stream, FT_Memory memory, PSAux_Service psaux ) { FT_Error error; FT_ULong base_offset, offset, ps_len; FT_Byte buffer[256 + 10]; FT_Int buff_len; FT_Byte *cur, *limit; FT_Byte *arg1, *arg2; FT_MEM_ZERO( parser, sizeof ( *parser ) ); psaux->ps_parser_funcs->init( &parser->root, 0, 0, memory ); parser->stream = stream; base_offset = FT_STREAM_POS(); /* first of all, check the font format in the header */ if ( FT_FRAME_ENTER( 31 ) ) goto Exit; if ( ft_strncmp( (char *)stream->cursor, "%!PS-Adobe-3.0 Resource-CIDFont", 31 ) ) { FT_TRACE2(( "[not a valid CID-keyed font]\n" )); error = CID_Err_Unknown_File_Format; } FT_FRAME_EXIT(); if ( error ) goto Exit; Again: /* now, read the rest of the file until we find a `StartData' */ buff_len = 256; for (;;) { FT_Byte* p; FT_ULong top_position; /* fill input buffer */ limit = buffer + 256; buff_len -= 256; if ( buff_len > 0 ) FT_MEM_MOVE( buffer, limit, buff_len ); p = buffer + buff_len; if ( FT_STREAM_READ( p, 256 + 10 - buff_len ) ) goto Exit; top_position = FT_STREAM_POS() - buff_len; buff_len = 256 + 10; /* look for `StartData' */ for ( p = buffer; p < limit; p++ ) { if ( p[0] == 'S' && ft_strncmp( (char*)p, "StartData", 9 ) == 0 ) { /* save offset of binary data after `StartData' */ offset = (FT_ULong)( top_position - ( limit - p ) + 10 ); goto Found; } } } Found: /* we have found the start of the binary data. We will now */ /* rewind and extract the frame corresponding to the PostScript */ /* section */ ps_len = offset - base_offset; if ( FT_STREAM_SEEK( base_offset ) || FT_FRAME_EXTRACT( ps_len, parser->postscript ) ) goto Exit; parser->data_offset = offset; parser->postscript_len = ps_len; parser->root.base = parser->postscript; parser->root.cursor = parser->postscript; parser->root.limit = parser->root.cursor + ps_len; parser->num_dict = -1; /* Finally, we check whether `StartData' was real -- it could be */ /* in a comment or string. We also get its arguments to find out */ /* whether the data is represented in binary or hex format. */ arg1 = parser->root.cursor; cid_parser_skip_PS_token( parser ); cid_parser_skip_spaces ( parser ); arg2 = parser->root.cursor; cid_parser_skip_PS_token( parser ); cid_parser_skip_spaces ( parser ); limit = parser->root.limit; cur = parser->root.cursor; while ( cur < limit ) { if ( parser->root.error ) break; if ( *cur == 'S' && ft_strncmp( (char*)cur, "StartData", 9 ) == 0 ) { if ( ft_strncmp( (char*)arg1, "(Hex)", 5 ) == 0 ) parser->binary_length = ft_atol( (const char *)arg2 ); limit = parser->root.limit; cur = parser->root.cursor; goto Exit; } cid_parser_skip_PS_token( parser ); cid_parser_skip_spaces ( parser ); arg1 = arg2; arg2 = cur; cur = parser->root.cursor; } /* we haven't found the correct `StartData'; go back and continue */ /* searching */ FT_FRAME_RELEASE( parser->postscript ); if ( !FT_STREAM_SEEK( offset ) ) goto Again; Exit: return error; } FT_LOCAL_DEF( void ) cid_parser_done( CID_Parser* parser ) { /* always free the private dictionary */ if ( parser->postscript ) { FT_Stream stream = parser->stream; FT_FRAME_RELEASE( parser->postscript ); } parser->root.funcs.done( &parser->root ); } /* END */ --- NEW FILE: type1cid.c --- /***************************************************************************/ /* */ /* type1cid.c */ /* */ /* FreeType OpenType driver component (body only). */ /* */ /* Copyright 1996-2001 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. */ /* */ /***************************************************************************/ #define FT_MAKE_OPTION_SINGLE_OBJECT #include <ft2build.h> #include "cidparse.c" #include "cidload.c" #include "cidobjs.c" #include "cidriver.c" #include "cidgload.c" /* END */ --- NEW FILE: cidriver.c --- /***************************************************************************/ /* */ /* cidriver.c */ /* */ /* CID driver interface (body). */ /* */ /* Copyright 1996-2001, 2002, 2003, 2004 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. */ /* */ /**... [truncated message content] |
Update of /cvsroot/roadmap/roadmap_editor/src/freetype/src/cache In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv22848/src/cache Added Files: ftcache.c ftcbasic.c ftccache.c ftccmap.c ftcglyph.c ftcimage.c ftcmanag.c ftcmru.c ftcsbits.c Log Message: Import freetype sources. --- NEW FILE: ftcache.c --- /***************************************************************************/ /* */ /* ftcache.c */ /* */ /* The FreeType Caching sub-system (body only). */ /* */ /* Copyright 2000-2001, 2003 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. */ /* */ /***************************************************************************/ #define FT_MAKE_OPTION_SINGLE_OBJECT #include <ft2build.h> #include "ftcmru.c" #include "ftcmanag.c" #include "ftccache.c" #include "ftccmap.c" #include "ftcglyph.c" #include "ftcimage.c" #include "ftcsbits.c" #include "ftcbasic.c" /* END */ --- NEW FILE: ftccmap.c --- /***************************************************************************/ /* */ /* ftccmap.c */ /* */ /* FreeType CharMap cache (body) */ /* */ /* Copyright 2000-2001, 2002, 2003, 2004, 2005 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_FREETYPE_H #include FT_CACHE_H #include FT_CACHE_INTERNAL_MANAGER_H #include FT_INTERNAL_MEMORY_H #include FT_INTERNAL_DEBUG_H #include FT_TRUETYPE_IDS_H #include "ftccback.h" #include "ftcerror.h" #undef FT_COMPONENT #define FT_COMPONENT trace_cache /*************************************************************************/ /* */ /* Each FTC_CMapNode contains a simple array to map a range of character */ /* codes to equivalent glyph indices. */ /* */ /* For now, the implementation is very basic: Each node maps a range of */ /* 128 consecutive character codes to their corresponding glyph indices. */ /* */ /* We could do more complex things, but I don't think it is really very */ /* useful. */ /* */ /*************************************************************************/ /* number of glyph indices / character code per node */ #define FTC_CMAP_INDICES_MAX 128 /* compute a query/node hash */ #define FTC_CMAP_HASH( faceid, index, charcode ) \ ( FTC_FACE_ID_HASH( faceid ) + 211 * ( index ) + \ ( (char_code) / FTC_CMAP_INDICES_MAX ) ) /* the charmap query */ typedef struct FTC_CMapQueryRec_ { FTC_FaceID face_id; FT_UInt cmap_index; FT_UInt32 char_code; } FTC_CMapQueryRec, *FTC_CMapQuery; #define FTC_CMAP_QUERY( x ) ((FTC_CMapQuery)(x)) #define FTC_CMAP_QUERY_HASH( x ) \ FTC_CMAP_HASH( (x)->face_id, (x)->cmap_index, (x)->char_code ) /* the cmap cache node */ typedef struct FTC_CMapNodeRec_ { FTC_NodeRec node; FTC_FaceID face_id; FT_UInt cmap_index; FT_UInt32 first; /* first character in node */ FT_UInt16 indices[FTC_CMAP_INDICES_MAX]; /* array of glyph indices */ } FTC_CMapNodeRec, *FTC_CMapNode; #define FTC_CMAP_NODE( x ) ( (FTC_CMapNode)( x ) ) #define FTC_CMAP_NODE_HASH( x ) \ FTC_CMAP_HASH( (x)->face_id, (x)->cmap_index, (x)->first ) /* if (indices[n] == FTC_CMAP_UNKNOWN), we assume that the corresponding */ /* glyph indices haven't been queried through FT_Get_Glyph_Index() yet */ #define FTC_CMAP_UNKNOWN ( (FT_UInt16)-1 ) /*************************************************************************/ /*************************************************************************/ /***** *****/ /***** CHARMAP NODES *****/ /***** *****/ /*************************************************************************/ /*************************************************************************/ /* no need for specific finalizer; we use `ftc_node_done' directly */ FT_CALLBACK_DEF( void ) ftc_cmap_node_free( FTC_Node ftcnode, FTC_Cache cache ) { FTC_CMapNode node = (FTC_CMapNode)ftcnode; FT_Memory memory = cache->memory; FT_FREE( node ); } /* initialize a new cmap node */ FT_CALLBACK_DEF( FT_Error ) ftc_cmap_node_new( FTC_Node *ftcanode, FT_Pointer ftcquery, FTC_Cache cache ) { FTC_CMapNode *anode = (FTC_CMapNode*)ftcanode; FTC_CMapQuery query = (FTC_CMapQuery)ftcquery; FT_Error error; FT_Memory memory = cache->memory; FTC_CMapNode node; FT_UInt nn; if ( !FT_NEW( node ) ) { node->face_id = query->face_id; node->cmap_index = query->cmap_index; node->first = (query->char_code / FTC_CMAP_INDICES_MAX) * FTC_CMAP_INDICES_MAX; for ( nn = 0; nn < FTC_CMAP_INDICES_MAX; nn++ ) node->indices[nn] = FTC_CMAP_UNKNOWN; } *anode = node; return error; } /* compute the weight of a given cmap node */ FT_CALLBACK_DEF( FT_ULong ) ftc_cmap_node_weight( FTC_Node cnode, FTC_Cache cache ) { FT_UNUSED( cnode ); FT_UNUSED( cache ); return sizeof ( *cnode ); } /* compare a cmap node to a given query */ FT_CALLBACK_DEF( FT_Bool ) ftc_cmap_node_compare( FTC_Node ftcnode, FT_Pointer ftcquery, FTC_Cache cache ) { FTC_CMapNode node = (FTC_CMapNode)ftcnode; FTC_CMapQuery query = (FTC_CMapQuery)ftcquery; FT_UNUSED( cache ); if ( node->face_id == query->face_id && node->cmap_index == query->cmap_index ) { FT_UInt32 offset = (FT_UInt32)( query->char_code - node->first ); return FT_BOOL( offset < FTC_CMAP_INDICES_MAX ); } return 0; } FT_CALLBACK_DEF( FT_Bool ) ftc_cmap_node_remove_faceid( FTC_Node ftcnode, FT_Pointer ftcface_id, FTC_Cache cache ) { FTC_CMapNode node = (FTC_CMapNode)ftcnode; FTC_FaceID face_id = (FTC_FaceID)ftcface_id; FT_UNUSED( cache ); return FT_BOOL( node->face_id == face_id ); } /*************************************************************************/ /*************************************************************************/ /***** *****/ /***** GLYPH IMAGE CACHE *****/ /***** *****/ /*************************************************************************/ /*************************************************************************/ FT_CALLBACK_TABLE_DEF const FTC_CacheClassRec ftc_cmap_cache_class = { ftc_cmap_node_new, ftc_cmap_node_weight, ftc_cmap_node_compare, ftc_cmap_node_remove_faceid, ftc_cmap_node_free, sizeof ( FTC_CacheRec ), ftc_cache_init, ftc_cache_done, }; /* documentation is in ftcache.h */ FT_EXPORT_DEF( FT_Error ) FTC_CMapCache_New( FTC_Manager manager, FTC_CMapCache *acache ) { return FTC_Manager_RegisterCache( manager, &ftc_cmap_cache_class, FTC_CACHE_P( acache ) ); } /* documentation is in ftcache.h */ FT_EXPORT_DEF( FT_UInt ) FTC_CMapCache_Lookup( FTC_CMapCache cmap_cache, FTC_FaceID face_id, FT_Int cmap_index, FT_UInt32 char_code ) { FTC_Cache cache = FTC_CACHE( cmap_cache ); FTC_CMapQueryRec query; FTC_CMapNode node; FT_Error error; FT_UInt gindex = 0; FT_UInt32 hash; if ( !cache ) { FT_ERROR(( "FTC_CMapCache_Lookup: bad arguments, returning 0!\n" )); return 0; } query.face_id = face_id; query.cmap_index = (FT_UInt)cmap_index; query.char_code = char_code; hash = FTC_CMAP_HASH( face_id, cmap_index, char_code ); #if 1 FTC_CACHE_LOOKUP_CMP( cache, ftc_cmap_node_compare, hash, &query, node, error ); #else error = FTC_Cache_Lookup( cache, hash, &query, (FTC_Node*) &node ); #endif if ( error ) goto Exit; FT_ASSERT( (FT_UInt)( char_code - node->first ) < FTC_CMAP_INDICES_MAX ); gindex = node->indices[char_code - node->first]; if ( gindex == FTC_CMAP_UNKNOWN ) { FT_Face face; gindex = 0; error = FTC_Manager_LookupFace( cache->manager, node->face_id, &face ); if ( error ) goto Exit; if ( (FT_UInt)cmap_index < (FT_UInt)face->num_charmaps ) { FT_CharMap old, cmap = NULL; old = face->charmap; cmap = face->charmaps[cmap_index]; if ( old != cmap ) FT_Set_Charmap( face, cmap ); gindex = FT_Get_Char_Index( face, char_code ); if ( old != cmap ) FT_Set_Charmap( face, old ); } node->indices[char_code - node->first] = (FT_UShort)gindex; } Exit: return gindex; } /* END */ --- NEW FILE: ftcimage.c --- /***************************************************************************/ /* */ /* ftcimage.c */ /* */ /* FreeType Image cache (body). */ /* */ /* Copyright 2000-2001, 2003, 2004 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_CACHE_H #include FT_CACHE_INTERNAL_IMAGE_H #include FT_INTERNAL_MEMORY_H #include "ftccback.h" #include "ftcerror.h" /* finalize a given glyph image node */ FT_LOCAL_DEF( void ) ftc_inode_free( FTC_Node ftcinode, FTC_Cache cache ) { FTC_INode inode = (FTC_INode)ftcinode; FT_Memory memory = cache->memory; if ( inode->glyph ) { FT_Done_Glyph( inode->glyph ); inode->glyph = NULL; } FTC_GNode_Done( FTC_GNODE( inode ), cache ); FT_FREE( inode ); } FT_EXPORT_DEF( void ) FTC_INode_Free( FTC_INode inode, FTC_Cache cache ) { ftc_inode_free( FTC_NODE( inode ), cache ); } /* initialize a new glyph image node */ FT_EXPORT_DEF( FT_Error ) FTC_INode_New( FTC_INode *pinode, FTC_GQuery gquery, FTC_Cache cache ) { FT_Memory memory = cache->memory; FT_Error error; FTC_INode inode; if ( !FT_NEW( inode ) ) { FTC_GNode gnode = FTC_GNODE( inode ); FTC_Family family = gquery->family; FT_UInt gindex = gquery->gindex; FTC_IFamilyClass clazz = FTC_CACHE__IFAMILY_CLASS( cache ); /* initialize its inner fields */ FTC_GNode_Init( gnode, gindex, family ); /* we will now load the glyph image */ error = clazz->family_load_glyph( family, gindex, cache, &inode->glyph ); } *pinode = inode; return error; } FT_LOCAL_DEF( FT_Error ) ftc_inode_new( FTC_Node *ftcpinode, FT_Pointer ftcgquery, FTC_Cache cache ) { FTC_INode *pinode = (FTC_INode*)ftcpinode; FTC_GQuery gquery = (FTC_GQuery)ftcgquery; return FTC_INode_New( pinode, gquery, cache ); } FT_LOCAL_DEF( FT_ULong ) ftc_inode_weight( FTC_Node ftcinode, FTC_Cache ftccache ) { FTC_INode inode = (FTC_INode)ftcinode; FT_ULong size = 0; FT_Glyph glyph = inode->glyph; FT_UNUSED( ftccache ); switch ( glyph->format ) { case FT_GLYPH_FORMAT_BITMAP: { FT_BitmapGlyph bitg; bitg = (FT_BitmapGlyph)glyph; size = bitg->bitmap.rows * labs( bitg->bitmap.pitch ) + sizeof ( *bitg ); } break; case FT_GLYPH_FORMAT_OUTLINE: { FT_OutlineGlyph outg; outg = (FT_OutlineGlyph)glyph; size = outg->outline.n_points * ( sizeof ( FT_Vector ) + sizeof ( FT_Byte ) ) + outg->outline.n_contours * sizeof ( FT_Short ) + sizeof ( *outg ); } break; default: ; } size += sizeof ( *inode ); return size; } FT_EXPORT_DEF( FT_ULong ) FTC_INode_Weight( FTC_INode inode ) { return ftc_inode_weight( FTC_NODE( inode ), NULL ); } /* END */ --- NEW FILE: ftcmanag.c --- /***************************************************************************/ /* */ /* ftcmanag.c */ /* */ /* FreeType Cache Manager (body). */ /* */ /* Copyright 2000-2001, 2002, 2003, 2004, 2005 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_CACHE_H #include FT_CACHE_INTERNAL_MANAGER_H #include FT_INTERNAL_OBJECTS_H #include FT_INTERNAL_DEBUG_H #include FT_SIZES_H #include "ftcerror.h" #undef FT_COMPONENT #define FT_COMPONENT trace_cache #define FTC_LRU_GET_MANAGER( lru ) ( (FTC_Manager)(lru)->user_data ) static FT_Error ftc_scaler_lookup_size( FTC_Manager manager, FTC_Scaler scaler, FT_Size *asize ) { FT_Face face; FT_Size size = NULL; FT_Error error; error = FTC_Manager_LookupFace( manager, scaler->face_id, &face ); if ( error ) goto Exit; error = FT_New_Size( face, &size ); if ( error ) goto Exit; FT_Activate_Size( size ); if ( scaler->pixel ) error = FT_Set_Pixel_Sizes( face, scaler->width, scaler->height ); else error = FT_Set_Char_Size( face, scaler->width, scaler->height, scaler->x_res, scaler->y_res ); if ( error ) { FT_Done_Size( size ); size = NULL; } Exit: *asize = size; return error; } typedef struct FTC_SizeNodeRec_ { FTC_MruNodeRec node; FT_Size size; FTC_ScalerRec scaler; } FTC_SizeNodeRec, *FTC_SizeNode; FT_CALLBACK_DEF( void ) ftc_size_node_done( FTC_MruNode ftcnode, FT_Pointer data ) { FTC_SizeNode node = (FTC_SizeNode)ftcnode; FT_Size size = node->size; FT_UNUSED( data ); if ( size ) FT_Done_Size( size ); } FT_CALLBACK_DEF( FT_Bool ) ftc_size_node_compare( FTC_MruNode ftcnode, FT_Pointer ftcscaler ) { FTC_SizeNode node = (FTC_SizeNode)ftcnode; FTC_Scaler scaler = (FTC_Scaler)ftcscaler; FTC_Scaler scaler0 = &node->scaler; if ( FTC_SCALER_COMPARE( scaler0, scaler ) ) { FT_Activate_Size( node->size ); return 1; } return 0; } FT_CALLBACK_DEF( FT_Error ) ftc_size_node_init( FTC_MruNode ftcnode, FT_Pointer ftcscaler, FT_Pointer ftcmanager ) { FTC_SizeNode node = (FTC_SizeNode)ftcnode; FTC_Scaler scaler = (FTC_Scaler)ftcscaler; FTC_Manager manager = (FTC_Manager)ftcmanager; node->scaler = scaler[0]; return ftc_scaler_lookup_size( manager, scaler, &node->size ); } FT_CALLBACK_DEF( FT_Error ) ftc_size_node_reset( FTC_MruNode ftcnode, FT_Pointer ftcscaler, FT_Pointer ftcmanager ) { FTC_SizeNode node = (FTC_SizeNode)ftcnode; FTC_Scaler scaler = (FTC_Scaler)ftcscaler; FTC_Manager manager = (FTC_Manager)ftcmanager; FT_Done_Size( node->size ); node->scaler = scaler[0]; return ftc_scaler_lookup_size( manager, scaler, &node->size ); } FT_CALLBACK_TABLE_DEF const FTC_MruListClassRec ftc_size_list_class = { sizeof ( FTC_SizeNodeRec ), ftc_size_node_compare, ftc_size_node_init, ftc_size_node_reset, ftc_size_node_done }; /* helper function used by ftc_face_node_done */ static FT_Bool ftc_size_node_compare_faceid( FTC_MruNode ftcnode, FT_Pointer ftcface_id ) { FTC_SizeNode node = (FTC_SizeNode)ftcnode; FTC_FaceID face_id = (FTC_FaceID)ftcface_id; return FT_BOOL( node->scaler.face_id == face_id ); } /* documentation is in ftcache.h */ FT_EXPORT_DEF( FT_Error ) FTC_Manager_LookupSize( FTC_Manager manager, FTC_Scaler scaler, FT_Size *asize ) { FT_Error error; FTC_SizeNode node; if ( asize == NULL ) return FTC_Err_Bad_Argument; *asize = NULL; if ( !manager ) return FTC_Err_Invalid_Cache_Handle; #ifdef FTC_INLINE FTC_MRULIST_LOOKUP_CMP( &manager->sizes, scaler, ftc_size_node_compare, node, error ); #else error = FTC_MruList_Lookup( &manager->sizes, scaler, (FTC_MruNode*)&node ); #endif if ( !error ) *asize = node->size; return error; } /*************************************************************************/ /*************************************************************************/ /***** *****/ /***** FACE MRU IMPLEMENTATION *****/ /***** *****/ /*************************************************************************/ /*************************************************************************/ typedef struct FTC_FaceNodeRec_ { FTC_MruNodeRec node; FTC_FaceID face_id; FT_Face face; } FTC_FaceNodeRec, *FTC_FaceNode; FT_CALLBACK_DEF( FT_Error ) ftc_face_node_init( FTC_MruNode ftcnode, FT_Pointer ftcface_id, FT_Pointer ftcmanager ) { FTC_FaceNode node = (FTC_FaceNode)ftcnode; FTC_FaceID face_id = (FTC_FaceID)ftcface_id; FTC_Manager manager = (FTC_Manager)ftcmanager; FT_Error error; node->face_id = face_id; error = manager->request_face( face_id, manager->library, manager->request_data, &node->face ); if ( !error ) { /* destroy initial size object; it will be re-created later */ if ( node->face->size ) FT_Done_Size( node->face->size ); } return error; } FT_CALLBACK_DEF( void ) ftc_face_node_done( FTC_MruNode ftcnode, FT_Pointer ftcmanager ) { FTC_FaceNode node = (FTC_FaceNode)ftcnode; FTC_Manager manager = (FTC_Manager)ftcmanager; /* we must begin by removing all scalers for the target face */ /* from the manager's list */ FTC_MruList_RemoveSelection( &manager->sizes, ftc_size_node_compare_faceid, node->face_id ); /* all right, we can discard the face now */ FT_Done_Face( node->face ); node->face = NULL; node->face_id = NULL; } FT_CALLBACK_DEF( FT_Bool ) ftc_face_node_compare( FTC_MruNode ftcnode, FT_Pointer ftcface_id ) { FTC_FaceNode node = (FTC_FaceNode)ftcnode; FTC_FaceID face_id = (FTC_FaceID)ftcface_id; return FT_BOOL( node->face_id == face_id ); } FT_CALLBACK_TABLE_DEF const FTC_MruListClassRec ftc_face_list_class = { sizeof ( FTC_FaceNodeRec), ftc_face_node_compare, ftc_face_node_init, 0, /* FTC_MruNode_ResetFunc */ ftc_face_node_done }; /* documentation is in ftcache.h */ FT_EXPORT_DEF( FT_Error ) FTC_Manager_LookupFace( FTC_Manager manager, FTC_FaceID face_id, FT_Face *aface ) { FT_Error error; FTC_FaceNode node; if ( aface == NULL ) return FTC_Err_Bad_Argument; *aface = NULL; if ( !manager ) return FTC_Err_Invalid_Cache_Handle; /* we break encapsulation for the sake of speed */ #ifdef FTC_INLINE FTC_MRULIST_LOOKUP_CMP( &manager->faces, face_id, ftc_face_node_compare, node, error ); #else error = FTC_MruList_Lookup( &manager->faces, face_id, (FTC_MruNode*)&node ); #endif if ( !error ) *aface = node->face; return error; } /*************************************************************************/ /*************************************************************************/ /***** *****/ /***** CACHE MANAGER ROUTINES *****/ /***** *****/ /*************************************************************************/ /*************************************************************************/ /* documentation is in ftcache.h */ FT_EXPORT_DEF( FT_Error ) FTC_Manager_New( FT_Library library, FT_UInt max_faces, FT_UInt max_sizes, FT_ULong max_bytes, FTC_Face_Requester requester, FT_Pointer req_data, FTC_Manager *amanager ) { FT_Error error; FT_Memory memory; FTC_Manager manager = 0; if ( !library ) return FTC_Err_Invalid_Library_Handle; memory = library->memory; if ( FT_NEW( manager ) ) goto Exit; if ( max_faces == 0 ) max_faces = FTC_MAX_FACES_DEFAULT; if ( max_sizes == 0 ) max_sizes = FTC_MAX_SIZES_DEFAULT; if ( max_bytes == 0 ) max_bytes = FTC_MAX_BYTES_DEFAULT; manager->library = library; manager->memory = memory; manager->max_weight = max_bytes; manager->request_face = requester; manager->request_data = req_data; FTC_MruList_Init( &manager->faces, &ftc_face_list_class, max_faces, manager, memory ); FTC_MruList_Init( &manager->sizes, &ftc_size_list_class, max_sizes, manager, memory ); *amanager = manager; Exit: return error; } /* documentation is in ftcache.h */ FT_EXPORT_DEF( void ) FTC_Manager_Done( FTC_Manager manager ) { FT_Memory memory; FT_UInt idx; if ( !manager || !manager->library ) return; memory = manager->memory; /* now discard all caches */ for (idx = manager->num_caches; idx-- > 0; ) { FTC_Cache cache = manager->caches[idx]; if ( cache ) { cache->clazz.cache_done( cache ); FT_FREE( cache ); manager->caches[idx] = NULL; } } manager->num_caches = 0; /* discard faces and sizes */ FTC_MruList_Done( &manager->sizes ); FTC_MruList_Done( &manager->faces ); manager->library = NULL; manager->memory = NULL; FT_FREE( manager ); } /* documentation is in ftcache.h */ FT_EXPORT_DEF( void ) FTC_Manager_Reset( FTC_Manager manager ) { if ( manager ) { FTC_MruList_Reset( &manager->sizes ); FTC_MruList_Reset( &manager->faces ); } /* XXX: FIXME: flush the caches? */ } #ifdef FT_DEBUG_ERROR FT_EXPORT_DEF( void ) FTC_Manager_Check( FTC_Manager manager ) { FTC_Node node, first; first = manager->nodes_list; /* check node weights */ if ( first ) { FT_ULong weight = 0; node = first; do { FTC_Cache cache = manager->caches[node->cache_index]; if ( (FT_UInt)node->cache_index >= manager->num_caches ) FT_ERROR(( "FTC_Manager_Check: invalid node (cache index = %ld\n", node->cache_index )); else weight += cache->clazz.node_weight( node, cache ); node = FTC_NODE__NEXT( node ); } while ( node != first ); if ( weight != manager->cur_weight ) FT_ERROR(( "FTC_Manager_Check: invalid weight %ld instead of %ld\n", manager->cur_weight, weight )); } /* check circular list */ if ( first ) { FT_UFast count = 0; node = first; do { count++; node = FTC_NODE__NEXT( node ); } while ( node != first ); if ( count != manager->num_nodes ) FT_ERROR(( "FTC_Manager_Check: invalid cache node count %d instead of %d\n", manager->num_nodes, count )); } } #endif /* FT_DEBUG_ERROR */ /* `Compress' the manager's data, i.e., get rid of old cache nodes */ /* that are not referenced anymore in order to limit the total */ /* memory used by the cache. */ /* documentation is in ftcmanag.h */ FT_EXPORT_DEF( void ) FTC_Manager_Compress( FTC_Manager manager ) { FTC_Node node, first; if ( !manager ) return; first = manager->nodes_list; #ifdef FT_DEBUG_ERROR FTC_Manager_Check( manager ); FT_ERROR(( "compressing, weight = %ld, max = %ld, nodes = %d\n", manager->cur_weight, manager->max_weight, manager->num_nodes )); #endif if ( manager->cur_weight < manager->max_weight || first == NULL ) return; /* go to last node -- it's a circular list */ node = FTC_NODE__PREV( first ); do { FTC_Node prev; prev = ( node == first ) ? NULL : FTC_NODE__PREV( node ); if ( node->ref_count <= 0 ) ftc_node_destroy( node, manager ); node = prev; } while ( node && manager->cur_weight > manager->max_weight ); } /* documentation is in ftcmanag.h */ FT_EXPORT_DEF( FT_Error ) FTC_Manager_RegisterCache( FTC_Manager manager, FTC_CacheClass clazz, FTC_Cache *acache ) { FT_Error error = FTC_Err_Invalid_Argument; FTC_Cache cache = NULL; if ( manager && clazz && acache ) { FT_Memory memory = manager->memory; if ( manager->num_caches >= FTC_MAX_CACHES ) { error = FTC_Err_Too_Many_Caches; FT_ERROR(( "%s: too many registered caches\n", "FTC_Manager_Register_Cache" )); goto Exit; } if ( !FT_ALLOC( cache, clazz->cache_size ) ) { cache->manager = manager; cache->memory = memory; cache->clazz = clazz[0]; cache->org_class = clazz; /* THIS IS VERY IMPORTANT! IT WILL WRETCH THE MANAGER */ /* IF IT IS NOT SET CORRECTLY */ cache->index = manager->num_caches; error = clazz->cache_init( cache ); if ( error ) { clazz->cache_done( cache ); FT_FREE( cache ); goto Exit; } manager->caches[manager->num_caches++] = cache; } } Exit: *acache = cache; return error; } FT_EXPORT_DEF( FT_UInt ) FTC_Manager_FlushN( FTC_Manager manager, FT_UInt count ) { FTC_Node first = manager->nodes_list; FTC_Node node; FT_UInt result; /* try to remove `count' nodes from the list */ if ( first == NULL ) /* empty list! */ return 0; /* go to last node - it's a circular list */ node = FTC_NODE__PREV(first); for ( result = 0; result < count; ) { FTC_Node prev = FTC_NODE__PREV( node ); /* don't touch locked nodes */ if ( node->ref_count <= 0 ) { ftc_node_destroy( node, manager ); result++; } if ( node == first ) break; node = prev; } return result; } /* documentation is in ftcache.h */ FT_EXPORT_DEF( void ) FTC_Manager_RemoveFaceID( FTC_Manager manager, FTC_FaceID face_id ) { FT_UInt nn; /* this will remove all FTC_SizeNode that correspond to * the face_id as well */ FTC_MruList_RemoveSelection( &manager->faces, NULL, face_id ); for ( nn = 0; nn < manager->num_caches; nn++ ) FTC_Cache_RemoveFaceID( manager->caches[nn], face_id ); } /* documentation is in ftcache.h */ FT_EXPORT_DEF( void ) FTC_Node_Unref( FTC_Node node, FTC_Manager manager ) { if ( node && (FT_UInt)node->cache_index < manager->num_caches ) node->ref_count--; } /* END */ --- NEW FILE: ftcmru.c --- /***************************************************************************/ /* */ /* ftcmru.c */ /* */ /* FreeType MRU support (body). */ /* */ /* Copyright 2003, 2004 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_CACHE_H #include FT_CACHE_INTERNAL_MRU_H #include FT_INTERNAL_OBJECTS_H #include FT_INTERNAL_DEBUG_H #include "ftcerror.h" FT_EXPORT_DEF( void ) FTC_MruNode_Prepend( FTC_MruNode *plist, FTC_MruNode node ) { FTC_MruNode first = *plist; if ( first ) { FTC_MruNode last = first->prev; #ifdef FT_DEBUG_ERROR { FTC_MruNode cnode = first; do { if ( cnode == node ) { fprintf( stderr, "FTC_MruNode_Prepend: invalid action!\n" ); exit( 2 ); } cnode = cnode->next; } while ( cnode != first ); } #endif first->prev = node; last->next = node; node->next = first; node->prev = last; } else { node->next = node; node->prev = node; } *plist = node; } FT_EXPORT_DEF( void ) FTC_MruNode_Up( FTC_MruNode *plist, FTC_MruNode node ) { FTC_MruNode first = *plist; FT_ASSERT( first != NULL ); if ( first != node ) { FTC_MruNode prev, next, last; #ifdef FT_DEBUG_ERROR { FTC_MruNode cnode = first; do { if ( cnode == node ) goto Ok; cnode = cnode->next; } while ( cnode != first ); fprintf( stderr, "FTC_MruNode_Up: invalid action!\n" ); exit( 2 ); Ok: } #endif prev = node->prev; next = node->next; prev->next = next; next->prev = prev; last = first->prev; last->next = node; first->prev = node; node->next = first; node->prev = last; *plist = node; } } FT_EXPORT_DEF( void ) FTC_MruNode_Remove( FTC_MruNode *plist, FTC_MruNode node ) { FTC_MruNode first = *plist; FTC_MruNode prev, next; FT_ASSERT( first != NULL ); #ifdef FT_DEBUG_ERROR { FTC_MruNode cnode = first; do { if ( cnode == node ) goto Ok; cnode = cnode->next; } while ( cnode != first ); fprintf( stderr, "FTC_MruNode_Remove: invalid action!\n" ); exit( 2 ); Ok: } #endif prev = node->prev; next = node->next; prev->next = next; next->prev = prev; if ( node == next ) { FT_ASSERT( first == node ); FT_ASSERT( prev == node ); *plist = NULL; } else if ( node == first ) *plist = next; } FT_EXPORT_DEF( void ) FTC_MruList_Init( FTC_MruList list, FTC_MruListClass clazz, FT_UInt max_nodes, FT_Pointer data, FT_Memory memory ) { list->num_nodes = 0; list->max_nodes = max_nodes; list->nodes = NULL; list->clazz = *clazz; list->data = data; list->memory = memory; } FT_EXPORT( void ) FTC_MruList_Reset( FTC_MruList list ) { while ( list->nodes ) FTC_MruList_Remove( list, list->nodes ); FT_ASSERT( list->num_nodes == 0 ); } FT_EXPORT( void ) FTC_MruList_Done( FTC_MruList list ) { FTC_MruList_Reset( list ); } FT_EXPORT_DEF( FTC_MruNode ) FTC_MruList_Find( FTC_MruList list, FT_Pointer key ) { FTC_MruNode_CompareFunc compare = list->clazz.node_compare; FTC_MruNode first, node; first = list->nodes; node = NULL; if ( first ) { node = first; do { if ( compare( node, key ) ) { if ( node != first ) FTC_MruNode_Up( &list->nodes, node ); return node; } node = node->next; } while ( node != first); } return NULL; } FT_EXPORT_DEF( FT_Error ) FTC_MruList_New( FTC_MruList list, FT_Pointer key, FTC_MruNode *anode ) { FT_Error error; FTC_MruNode node; FT_Memory memory = list->memory; if ( list->num_nodes >= list->max_nodes && list->max_nodes > 0 ) { node = list->nodes->prev; FT_ASSERT( node ); if ( list->clazz.node_reset ) { FTC_MruNode_Up( &list->nodes, node ); error = list->clazz.node_reset( node, key, list->data ); if ( !error ) goto Exit; } FTC_MruNode_Remove( &list->nodes, node ); list->num_nodes--; if ( list->clazz.node_done ) list->clazz.node_done( node, list->data ); } else if ( FT_ALLOC( node, list->clazz.node_size ) ) goto Exit; error = list->clazz.node_init( node, key, list->data ); if ( error ) goto Fail; FTC_MruNode_Prepend( &list->nodes, node ); list->num_nodes++; Exit: *anode = node; return error; Fail: if ( list->clazz.node_done ) list->clazz.node_done( node, list->data ); FT_FREE( node ); goto Exit; } FT_EXPORT( FT_Error ) FTC_MruList_Lookup( FTC_MruList list, FT_Pointer key, FTC_MruNode *anode ) { FTC_MruNode node; node = FTC_MruList_Find( list, key ); if ( node == NULL ) return FTC_MruList_New( list, key, anode ); *anode = node; return 0; } FT_EXPORT_DEF( void ) FTC_MruList_Remove( FTC_MruList list, FTC_MruNode node ) { FTC_MruNode_Remove( &list->nodes, node ); list->num_nodes--; { FT_Memory memory = list->memory; if ( list->clazz.node_done ) list->clazz.node_done( node, list->data ); FT_FREE( node ); } } FT_EXPORT_DEF( void ) FTC_MruList_RemoveSelection( FTC_MruList list, FTC_MruNode_CompareFunc selection, FT_Pointer key ) { FTC_MruNode first, node, next; first = list->nodes; while ( first && ( selection == NULL || selection( first, key ) ) ) { FTC_MruList_Remove( list, first ); first = list->nodes; } if ( first ) { node = first->next; while ( node != first ) { next = node->next; if ( selection( node, key ) ) FTC_MruList_Remove( list, node ); node = next; } } } /* END */ --- NEW FILE: ftccache.c --- /***************************************************************************/ /* */ /* ftccache.c */ /* */ /* The FreeType internal cache interface (body). */ /* */ /* Copyright 2000-2001, 2002, 2003, 2004, 2005 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_CACHE_INTERNAL_MANAGER_H #include FT_INTERNAL_OBJECTS_H #include FT_INTERNAL_DEBUG_H #include "ftccback.h" #include "ftcerror.h" #define FTC_HASH_MAX_LOAD 2 #define FTC_HASH_MIN_LOAD 1 #define FTC_HASH_SUB_LOAD ( FTC_HASH_MAX_LOAD - FTC_HASH_MIN_LOAD ) /* this one _must_ be a power of 2! */ #define FTC_HASH_INITIAL_SIZE 8 /*************************************************************************/ /*************************************************************************/ /***** *****/ /***** CACHE NODE DEFINITIONS *****/ /***** *****/ /*************************************************************************/ /*************************************************************************/ /* add a new node to the head of the manager's circular MRU list */ static void ftc_node_mru_link( FTC_Node node, FTC_Manager manager ) { FTC_MruNode_Prepend( (FTC_MruNode*)&manager->nodes_list, (FTC_MruNode)node ); manager->num_nodes++; } /* remove a node from the manager's MRU list */ static void ftc_node_mru_unlink( FTC_Node node, FTC_Manager manager ) { FTC_MruNode_Remove( (FTC_MruNode*)&manager->nodes_list, (FTC_MruNode)node ); manager->num_nodes--; } /* move a node to the head of the manager's MRU list */ static void ftc_node_mru_up( FTC_Node node, FTC_Manager manager ) { FTC_MruNode_Up( (FTC_MruNode*)&manager->nodes_list, (FTC_MruNode)node ); } /* Note that this function cannot fail. If we cannot re-size the * buckets array appropriately, we simply degrade the hash table's * performance! */ static void ftc_cache_resize( FTC_Cache cache ) { for (;;) { FTC_Node node, *pnode; FT_UInt p = cache->p; FT_UInt mask = cache->mask; FT_UInt count = mask + p + 1; /* number of buckets */ /* do we need to shrink the buckets array? */ if ( cache->slack < 0 ) { FTC_Node new_list = NULL; /* try to expand the buckets array _before_ splitting * the bucket lists */ if ( p >= mask ) { FT_Memory memory = cache->memory; /* if we can't expand the array, leave immediately */ if ( FT_MEM_RENEW_ARRAY( cache->buckets, (mask+1)*2, (mask+1)*4 ) ) break; } /* split a single bucket */ pnode = cache->buckets + p; for (;;) { node = *pnode; if ( node == NULL ) break; if ( node->hash & ( mask + 1 ) ) { *pnode = node->link; node->link = new_list; new_list = node; } else pnode = &node->link; } cache->buckets[p + mask + 1] = new_list; cache->slack += FTC_HASH_MAX_LOAD; if ( p >= mask ) { cache->mask = 2 * mask + 1; cache->p = 0; } else cache->p = p + 1; } /* do we need to expand the buckets array? */ else if ( cache->slack > (FT_Long)count * FTC_HASH_SUB_LOAD ) { FT_UInt old_index = p + mask; FTC_Node* pold; if ( old_index + 1 <= FTC_HASH_INITIAL_SIZE ) break; if ( p == 0 ) { FT_Memory memory = cache->memory; /* if we can't shrink the array, leave immediately */ if ( FT_MEM_RENEW_ARRAY( cache->buckets, ( mask + 1 ) * 2, mask + 1 ) ) break; cache->mask >>= 1; p = cache->mask; } else p--; pnode = cache->buckets + p; while ( *pnode ) pnode = &(*pnode)->link; pold = cache->buckets + old_index; *pnode = *pold; *pold = NULL; cache->slack -= FTC_HASH_MAX_LOAD; cache->p = p; } else /* the hash table is balanced */ break; } } /* remove a node from its cache's hash table */ static void ftc_node_hash_unlink( FTC_Node node0, FTC_Cache cache ) { FTC_Node *pnode; FT_UInt idx; idx = (FT_UInt)( node0->hash & cache->mask ); if ( idx < cache->p ) idx = (FT_UInt)( node0->hash & ( 2 * cache->mask + 1 ) ); pnode = cache->buckets + idx; for (;;) { FTC_Node node = *pnode; if ( node == NULL ) { FT_ERROR(( "ftc_node_hash_unlink: unknown node!\n" )); return; } if ( node == node0 ) break; pnode = &(*pnode)->link; } *pnode = node0->link; node0->link = NULL; cache->slack++; ftc_cache_resize( cache ); } /* add a node to the `top' of its cache's hash table */ static void ftc_node_hash_link( FTC_Node node, FTC_Cache cache ) { FTC_Node *pnode; FT_UInt idx; idx = (FT_UInt)( node->hash & cache->mask ); if ( idx < cache->p ) idx = (FT_UInt)( node->hash & (2 * cache->mask + 1 ) ); pnode = cache->buckets + idx; node->link = *pnode; *pnode = node; cache->slack--; ftc_cache_resize( cache ); } /* remove a node from the cache manager */ FT_EXPORT_DEF( void ) ftc_node_destroy( FTC_Node node, FTC_Manager manager ) { FTC_Cache cache; #ifdef FT_DEBUG_ERROR /* find node's cache */ if ( node->cache_index >= manager->num_caches ) { FT_ERROR(( "ftc_node_destroy: invalid node handle\n" )); return; } #endif cache = manager->caches[node->cache_index]; #ifdef FT_DEBUG_ERROR if ( cache == NULL ) { FT_ERROR(( "ftc_node_destroy: invalid node handle\n" )); return; } #endif manager->cur_weight -= cache->clazz.node_weight( node, cache ); /* remove node from mru list */ ftc_node_mru_unlink( node, manager ); /* remove node from cache's hash table */ ftc_node_hash_unlink( node, cache ); /* now finalize it */ cache->clazz.node_free( node, cache ); #if 0 /* check, just in case of general corruption :-) */ if ( manager->num_nodes == 0 ) FT_ERROR(( "ftc_node_destroy: invalid cache node count! = %d\n", manager->num_nodes )); #endif } /*************************************************************************/ /*************************************************************************/ /***** *****/ /***** ABSTRACT CACHE CLASS *****/ /***** *****/ /*************************************************************************/ /*************************************************************************/ FT_EXPORT_DEF( FT_Error ) FTC_Cache_Init( FTC_Cache cache ) { return ftc_cache_init( cache ); } FT_LOCAL_DEF( FT_Error ) ftc_cache_init( FTC_Cache cache ) { FT_Memory memory = cache->memory; cache->p = 0; cache->mask = FTC_HASH_INITIAL_SIZE - 1; cache->slack = FTC_HASH_INITIAL_SIZE * FTC_HASH_MAX_LOAD; return ( FT_MEM_NEW_ARRAY( cache->buckets, FTC_HASH_INITIAL_SIZE * 2 ) ); } FT_EXPORT_DEF( void ) FTC_Cache_Clear( FTC_Cache cache ) { if ( cache ) { FTC_Manager manager = cache->manager; FT_UFast i; FT_UInt count; count = cache->p + cache->mask + 1; for ( i = 0; i < count; i++ ) { FTC_Node *pnode = cache->buckets + i, next, node = *pnode; while ( node ) { next = node->link; node->link = NULL; /* remove node from mru list */ ftc_node_mru_unlink( node, manager ); /* now finalize it */ manager->cur_weight -= cache->clazz.node_weight( node, cache ); cache->clazz.node_free( node, cache ); node = next; } cache->buckets[i] = NULL; } ftc_cache_resize( cache ); } } FT_LOCAL_DEF( void ) ftc_cache_done( FTC_Cache cache ) { if ( cache->memory ) { FT_Memory memory = cache->memory; FTC_Cache_Clear( cache ); FT_FREE( cache->buckets ); cache->mask = 0; cache->p = 0; cache->slack = 0; cache->memory = NULL; } } FT_EXPORT_DEF( void ) FTC_Cache_Done( FTC_Cache cache ) { ftc_cache_done( cache ); } static void ftc_cache_add( FTC_Cache cache, FT_UInt32 hash, FTC_Node node ) { node->hash = hash; node->cache_index = (FT_UInt16) cache->index; node->ref_count = 0; ftc_node_hash_link( node, cache ); ftc_node_mru_link( node, cache->manager ); { FTC_Manager manager = cache->manager; manager->cur_weight += cache->clazz.node_weight( node, cache ); if ( manager->cur_weight >= manager->max_weight ) { node->ref_count++; FTC_Manager_Compress( manager ); node->ref_count--; } } } FT_EXPORT_DEF( FT_Error ) FTC_Cache_NewNode( FTC_Cache cache, FT_UInt32 hash, FT_Pointer query, FTC_Node *anode ) { FT_Error error; FTC_Node node; /* * We use the FTC_CACHE_TRYLOOP macros to support out-of-memory * errors (OOM) correctly, i.e., by flushing the cache progressively * in order to make more room. */ FTC_CACHE_TRYLOOP( cache ) { error = cache->clazz.node_new( &node, query, cache ); } FTC_CACHE_TRYLOOP_END(); if ( error ) node = NULL; else { /* don't assume that the cache has the same number of buckets, since * our allocation request might have triggered global cache flushing */ ftc_cache_add( cache, hash, node ); } *anode = node; return error; } FT_EXPORT_DEF( FT_Error ) FTC_Cache_Lookup( FTC_Cache cache, FT_UInt32 hash, FT_Pointer query, FTC_Node *anode ) { FT_UFast idx; FTC_Node* bucket; FTC_Node* pnode; FTC_Node node; FT_Error error = 0; FTC_Node_CompareFunc compare = cache->clazz.node_compare; if ( cache == NULL || anode == NULL ) return FT_Err_Invalid_Argument; idx = hash & cache->mask; if ( idx < cache->p ) idx = hash & ( cache->mask * 2 + 1 ); bucket = cache->buckets + idx; pnode = bucket; for (;;) { node = *pnode; if ( node == NULL ) goto NewNode; if ( node->hash == hash && compare( node, query, cache ) ) break; pnode = &node->link; } if ( node != *bucket ) { *pnode = node->link; node->link = *bucket; *bucket = node; } /* move to head of MRU list */ { FTC_Manager manager = cache->manager; if ( node != manager->nodes_list ) ftc_node_mru_up( node, manager ); } *anode = node; return error; NewNode: return FTC_Cache_NewNode( cache, hash, query, anode ); } FT_EXPORT_DEF( void ) FTC_Cache_RemoveFaceID( FTC_Cache cache, FTC_FaceID face_id ) { FT_UFast i, count; FTC_Manager manager = cache->manager; FTC_Node frees = NULL; count = cache->p + cache->mask; for ( i = 0; i < count; i++ ) { FTC_Node* bucket = cache->buckets + i; FTC_Node* pnode = bucket; for ( ;; ) { FTC_Node node = *pnode; if ( node == NULL ) break; if ( cache->clazz.node_remove_faceid( node, face_id, cache ) ) { *pnode = node->link; node->link = frees; frees = node; } else pnode = &node->link; } } /* remove all nodes in the free list */ while ( frees ) { FTC_Node node; node = frees; frees = node->link; manager->cur_weight -= cache->clazz.node_weight( node, cache ); ftc_node_mru_unlink( node, manager ); cache->clazz.node_free( node, cache ); cache->slack++; } ftc_cache_resize( cache ); } /* END */ --- NEW FILE: ftcglyph.c --- /***************************************************************************/ /* */ /* ftcglyph.c */ /* */ /* FreeType Glyph Image (FT_Glyph) cache (body). */ /* */ /* Copyright 2000-2001, 2003, 2004 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_CACHE_H #include FT_CACHE_INTERNAL_GLYPH_H #include FT_ERRORS_H #include FT_INTERNAL_OBJECTS_H #include FT_INTERNAL_DEBUG_H #include "ftccback.h" #include "ftcerror.h" /* create a new chunk node, setting its cache index and ref count */ FT_EXPORT_DEF( void ) FTC_GNode_Init( FTC_GNode gnode, FT_UInt gindex, FTC_Family family ) { gnode->family = family; gnode->gindex = gindex; family->num_nodes++; } FT_EXPORT_DEF( void ) FTC_GNode_UnselectFamily( FTC_GNode gnode, FTC_Cache cache ) { FTC_Family family = gnode->family; gnode->family = NULL; if ( family && --family->num_nodes == 0 ) FTC_FAMILY_FREE( family, cache ); } FT_EXPORT_DEF( void ) FTC_GNode_Done( FTC_GNode gnode, FTC_Cache cache ) { /* finalize the node */ gnode->gindex = 0; FTC_GNode_UnselectFamily( gnode, cache ); } FT_LOCAL_DEF( FT_Bool ) ftc_gnode_compare( FTC_Node ftcgnode, FT_Pointer ftcgquery, FTC_Cache cache ) { FTC_GNode gnode = (FTC_GNode)ftcgnode; FTC_GQuery gquery = (FTC_GQuery)ftcgquery; FT_UNUSED( cache ); return FT_BOOL( gnode->family == gquery->family && gnode->gindex == gquery->gindex ); } FT_EXPORT_DEF( FT_Bool ) FTC_GNode_Compare( FTC_GNode gnode, FTC_GQuery gquery ) { return ftc_gnode_compare( FTC_NODE( gnode ), gquery, NULL ); } /*************************************************************************/ /*************************************************************************/ /***** *****/ /***** CHUNK SETS *****/ /***** *****/ /*************************************************************************/ /*************************************************************************/ FT_EXPORT_DEF( void ) FTC_Family_Init( FTC_Family family, FTC_Cache cache ) { FTC_GCacheClass clazz = FTC_CACHE__GCACHE_CLASS( cache ); family->clazz = clazz->family_class; family->num_nodes = 0; family->cache = cache; } FT_LOCAL_DEF( FT_Error ) ftc_gcache_init( FTC_Cache ftccache ) { FTC_GCache cache = (FTC_GCache)ftccache; FT_Error error; error = FTC_Cache_Init( FTC_CACHE( cache ) ); if ( !error ) { FTC_GCacheClass clazz = (FTC_GCacheClass)FTC_CACHE( cache )->org_class; FTC_MruList_Init( &cache->families, clazz->family_class, 0, /* no maximum here! */ cache, FTC_CACHE( cache )->memory ); } return error; } FT_EXPORT_DEF( FT_Error ) FTC_GCache_Init( FTC_GCache cache ) { return ftc_gcache_init( FTC_CACHE( cache ) ); } FT_LOCAL_DEF( void ) ftc_gcache_done( FTC_Cache ftccache ) { FTC_GCache cache = (FTC_GCache)ftccache; FTC_Cache_Done( (FTC_Cache)cache ); FTC_MruList_Done( &cache->families ); } FT_EXPORT_DEF( void ) FTC_GCache_Done( FTC_GCache cache ) { ftc_gcache_done( FTC_CACHE( cache ) ); } FT_EXPORT_DEF( FT_Error ) FTC_GCache_New( FTC_Manager manager, FTC_GCacheClass clazz, FTC_GCache *acache ) { return FTC_Manager_RegisterCache( manager, (FTC_CacheClass)clazz, (FTC_Cache*)acache ); } FT_EXPORT_DEF( FT_Error ) FTC_GCache_Lookup( FTC_GCache cache, FT_UInt32 hash, FT_UInt gindex, FTC_GQuery query, FTC_Node *anode ) { FT_Error error; query->gindex = gindex; FTC_MRULIST_LOOKUP( &cache->families, query, query->family, error ); if ( !error ) { FTC_Family family = query->family; /* prevent the family from being destroyed too early when an */ /* out-of-memory condition occurs during glyph node initialization. */ family->num_nodes++; error = FTC_Cache_Lookup( FTC_CACHE( cache ), hash, query, anode ); if ( --family->num_nodes == 0 ) FTC_FAMILY_FREE( family, cache ); } return error; } /* END */ --- NEW FILE: ftcsbits.c --- /***************************************************************************/ /* */ /* ftcsbits.c */ /* */ /* FreeType... [truncated message content] |
|
From: Ehud S. <esh...@us...> - 2006-04-21 16:22:38
|
Update of /cvsroot/roadmap/roadmap_editor/src/freetype/include/freetype/config In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv22848/include/freetype/config Added Files: ftconfig.h ftheader.h ftmodule.h ftoption.h ftstdlib.h Log Message: Import freetype sources. --- NEW FILE: ftoption.h --- /***************************************************************************/ /* */ /* ftoption.h */ /* */ /* User-selectable configuration macros (specification only). */ /* */ /* Copyright 1996-2001, 2002, 2003, 2004, 2005 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. */ /* */ /***************************************************************************/ #ifndef __FTOPTION_H__ #define __FTOPTION_H__ #include <ft2build.h> FT_BEGIN_HEADER /*************************************************************************/ /* */ /* USER-SELECTABLE CONFIGURATION MACROS */ /* */ /* This file contains the default configuration macro definitions for */ /* a standard build of the FreeType library. There are three ways to */ /* use this file to build project-specific versions of the library: */ /* */ /* - You can modify this file by hand, but this is not recommended in */ /* cases where you would like to build several versions of the */ /* library from a single source directory. */ /* */ /* - You can put a copy of this file in your build directory, more */ /* precisely in "$BUILD/freetype/config/ftoption.h", where "$BUILD" */ /* is the name of a directory that is included _before_ the FreeType */ /* include path during compilation. */ /* */ /* The default FreeType Makefiles and Jamfiles use the build */ /* directory "builds/<system>" by default, but you can easily change */ /* that for your own projects. */ /* */ /* - Copy the file <ft2build.h> to "$BUILD/ft2build.h" and modify it */ /* slightly to pre-define the macro FT_CONFIG_OPTIONS_H used to */ /* locate this file during the build. For example, */ /* */ /* #define FT_CONFIG_OPTIONS_H <myftoptions.h> */ /* #include <freetype/config/ftheader.h> */ /* */ /* will use "$BUILD/myftoptions.h" instead of this file for macro */ /* definitions. */ /* */ /* Note also that you can similarly pre-define the macro */ /* FT_CONFIG_MODULES_H used to locate the file listing of the modules */ /* that are statically linked to the library at compile time. By */ /* default, this file is <freetype/config/ftmodule.h>. */ /* */ /* We highly recommend using the third method whenever possible. */ /* */ /*************************************************************************/ /*************************************************************************/ /*************************************************************************/ /**** ****/ /**** G E N E R A L F R E E T Y P E 2 C O N F I G U R A T I O N ****/ /**** ****/ /*************************************************************************/ /*************************************************************************/ /*************************************************************************/ /* */ /* Many compilers provide a non-ANSI 64-bit data type that can be used */ /* by FreeType to speed up some computations. However, this will create */ /* some problems when compiling the library in strict ANSI mode. */ /* */ /* For this reason, the use of 64-bit integers is normally disabled when */ /* the __STDC__ macro is defined. You can however disable this by */ /* defining the macro FT_CONFIG_OPTION_FORCE_INT64 here. */ /* */ /* For most compilers, this will only create compilation warnings when */ /* building the library. */ /* */ /* ObNote: The compiler-specific 64-bit integers are detected in the */ /* file "ftconfig.h" either statically or through the */ /* `configure' script on supported platforms. */ /* */ #undef FT_CONFIG_OPTION_FORCE_INT64 /*************************************************************************/ /* */ /* LZW-compressed file support. */ /* */ /* FreeType now handles font files that have been compressed with the */ /* 'compress' program. This is mostly used to parse many of the PCF */ /* files that come with various X11 distributions. The implementation */ /* uses NetBSD's `zopen' to partially uncompress the file on the fly */ /* (see src/lzw/ftgzip.c). */ /* */ /* Define this macro if you want to enable this `feature'. */ /* */ /* #define FT_CONFIG_OPTION_USE_LZW */ /*************************************************************************/ /* */ /* Gzip-compressed file support. */ /* */ /* FreeType now handles font files that have been compressed with the */ /* 'gzip' program. This is mostly used to parse many of the PCF files */ /* that come with XFree86. The implementation uses `zlib' to */ /* partially uncompress the file on the fly (see src/gzip/ftgzip.c). */ /* */ /* Define this macro if you want to enable this `feature'. See also */ /* the macro FT_CONFIG_OPTION_SYSTEM_ZLIB below. */ /* */ /* #define FT_CONFIG_OPTION_USE_ZLIB */ /*************************************************************************/ /* */ /* ZLib library selection */ /* */ /* This macro is only used when FT_CONFIG_OPTION_USE_ZLIB is defined. */ /* It allows FreeType's `ftgzip' component to link to the system's */ /* installation of the ZLib library. This is useful on systems like */ /* Unix or VMS where it generally is already available. */ /* */ /* If you let it undefined, the component will use its own copy */ /* of the zlib sources instead. These have been modified to be */ /* included directly within the component and *not* export external */ /* function names. This allows you to link any program with FreeType */ /* _and_ ZLib without linking conflicts. */ /* */ /* Do not #undef this macro here since the build system might define */ /* it for certain configurations only. */ /* */ /* #define FT_CONFIG_OPTION_SYSTEM_ZLIB */ /*************************************************************************/ /* */ /* DLL export compilation */ /* */ /* When compiling FreeType as a DLL, some systems/compilers need a */ /* special keyword in front OR after the return type of function */ /* declarations. */ /* */ /* Two macros are used within the FreeType source code to define */ /* exported library functions: FT_EXPORT and FT_EXPORT_DEF. */ /* */ /* FT_EXPORT( return_type ) */ /* */ /* is used in a function declaration, as in */ /* */ /* FT_EXPORT( FT_Error ) */ /* FT_Init_FreeType( FT_Library* alibrary ); */ /* */ /* */ /* FT_EXPORT_DEF( return_type ) */ /* */ /* is used in a function definition, as in */ /* */ /* FT_EXPORT_DEF( FT_Error ) */ /* FT_Init_FreeType( FT_Library* alibrary ) */ /* { */ /* ... some code ... */ /* return FT_Err_Ok; */ /* } */ /* */ /* You can provide your own implementation of FT_EXPORT and */ /* FT_EXPORT_DEF here if you want. If you leave them undefined, they */ /* will be later automatically defined as `extern return_type' to */ /* allow normal compilation. */ /* */ /* Do not #undef these macros here since the build system might define */ /* them for certain configurations only. */ /* */ /* #define FT_EXPORT(x) extern x */ /* #define FT_EXPORT_DEF(x) x */ /*************************************************************************/ /* */ /* Glyph Postscript Names handling */ /* */ /* By default, FreeType 2 is compiled with the `PSNames' module. This */ /* module is in charge of converting a glyph name string into a */ /* Unicode value, or return a Macintosh standard glyph name for the */ /* use with the TrueType `post' table. */ /* */ /* Undefine this macro if you do not want `PSNames' compiled in your */ /* build of FreeType. This has the following effects: */ /* */ /* - The TrueType driver will provide its own set of glyph names, */ /* if you build it to support postscript names in the TrueType */ /* `post' table. */ /* */ /* - The Type 1 driver will not be able to synthetize a Unicode */ /* charmap out of the glyphs found in the fonts. */ /* */ /* You would normally undefine this configuration macro when building */ /* a version of FreeType that doesn't contain a Type 1 or CFF driver. */ /* */ /* #define FT_CONFIG_OPTION_POSTSCRIPT_NAMES */ /*************************************************************************/ /* */ /* Postscript Names to Unicode Values support */ /* */ /* By default, FreeType 2 is built with the `PSNames' module compiled */ /* in. Among other things, the module is used to convert a glyph name */ /* into a Unicode value. This is especially useful in order to */ /* synthetize on the fly a Unicode charmap from the CFF/Type 1 driver */ /* through a big table named the `Adobe Glyph List' (AGL). */ /* */ /* Undefine this macro if you do not want the Adobe Glyph List */ /* compiled in your `PSNames' module. The Type 1 driver will not be */ /* able to synthetize a Unicode charmap out of the glyphs found in the */ /* fonts. */ /* */ #define FT_CONFIG_OPTION_ADOBE_GLYPH_LIST /*************************************************************************/ /* */ /* Support for Mac fonts */ /* */ /* Define this macro if you want support for outline fonts in Mac */ /* format (mac dfont, mac resource, macbinary containing a mac */ /* resource) on non-Mac platforms. */ /* */ /* Note that the `FOND' resource isn't checked. */ /* */ /* #define FT_CONFIG_OPTION_MAC_FONTS */ /*************************************************************************/ /* */ /* Guessing methods to access embedded resource forks */ /* */ /* Enable extra Mac fonts support on non-Mac platforms (e.g. */ /* GNU/Linux). */ /* */ /* Resource forks which include fonts data are stored sometimes in */ /* locations which users or developers don't expected. In some cases, */ /* resource forks start with some offset from the head of a file. In */ /* other cases, the actual resource fork is stored in file different */ /* from what the user specifies. If this option is activated, */ /* FreeType tries to guess whether such offsets or different file */ /* names must be used. */ /* */ /* Note that normal, direct access of resource forks is controlled via */ /* the FT_CONFIG_OPTION_MAC_FONTS option. */ /* */ #ifdef FT_CONFIG_OPTION_MAC_FONTS #define FT_CONFIG_OPTION_GUESSING_EMBEDDED_RFORK #endif /*************************************************************************/ /* */ /* Allow the use of FT_Incremental_Interface to load typefaces that */ /* contain no glyph data, but supply it via a callback function. */ /* This allows FreeType to be used with the PostScript language, using */ /* the GhostScript interpreter. */ /* */ /* #define FT_CONFIG_OPTION_INCREMENTAL */ /*************************************************************************/ /* */ /* The size in bytes of the render pool used by the scan-line converter */ /* to do all of its work. */ /* */ /* This must be greater than 4KByte. */ /* */ #define FT_RENDER_POOL_SIZE 16384L /*************************************************************************/ /* */ /* FT_MAX_MODULES */ /* */ /* The maximum number of modules that can be registered in a single */ /* FreeType library object. 32 is the default. */ /* */ #define FT_MAX_MODULES 10 /*************************************************************************/ /* */ /* Debug level */ /* */ /* FreeType can be compiled in debug or trace mode. In debug mode, */ /* errors are reported through the `ftdebug' component. In trace */ /* mode, additional messages are sent to the standard output during */ /* execution. */ /* */ /* Define FT_DEBUG_LEVEL_ERROR to build the library in debug mode. */ /* Define FT_DEBUG_LEVEL_TRACE to build it in trace mode. */ /* */ /* Don't define any of these macros to compile in `release' mode! */ /* */ /* Do not #undef these macros here since the build system might define */ /* them for certain configurations only. */ /* */ /* #define FT_DEBUG_LEVEL_ERROR */ /* #define FT_DEBUG_LEVEL_TRACE */ /*************************************************************************/ /* */ /* Memory Debugging */ /* */ /* FreeType now comes with an integrated memory debugger that is */ /* capable of detecting simple errors like memory leaks or double */ /* deletes. To compile it within your build of the library, you */ /* should define FT_DEBUG_MEMORY here. */ /* */ /* Note that the memory debugger is only activated at runtime when */ /* when the _environment_ variable "FT2_DEBUG_MEMORY" is defined also! */ /* */ /* Do not #undef this macro here since the build system might define */ /* it for certain configurations only. */ /* */ /* #define FT_DEBUG_MEMORY */ /*************************************************************************/ /* */ /* Module errors */ /* */ /* If this macro is set (which is _not_ the default), the higher byte */ /* of an error code gives the module in which the error has occurred, */ /* while the lower byte is the real error code. */ /* */ /* Setting this macro makes sense for debugging purposes only, since */ /* it would break source compatibility of certain programs that use */ /* FreeType 2. */ /* */ /* More details can be found in the files ftmoderr.h and fterrors.h. */ /* */ #undef FT_CONFIG_OPTION_USE_MODULE_ERRORS /*************************************************************************/ /*************************************************************************/ /**** ****/ /**** S F N T D R I V E R C O N F I G U R A T I O N ****/ /**** ****/ /*************************************************************************/ /*************************************************************************/ /*************************************************************************/ /* */ /* Define TT_CONFIG_OPTION_EMBEDDED_BITMAPS if you want to support */ /* embedded bitmaps in all formats using the SFNT module (namely */ /* TrueType & OpenType). */ /* */ /* #define TT_CONFIG_OPTION_EMBEDDED_BITMAPS */ /*************************************************************************/ /* */ /* Define TT_CONFIG_OPTION_POSTSCRIPT_NAMES if you want to be able to */ /* load and enumerate the glyph Postscript names in a TrueType or */ /* OpenType file. */ /* */ /* Note that when you do not compile the `PSNames' module by undefining */ /* the above FT_CONFIG_OPTION_POSTSCRIPT_NAMES, the `sfnt' module will */ /* contain additional code used to read the PS Names table from a font. */ /* */ /* (By default, the module uses `PSNames' to extract glyph names.) */ /* */ /* #define TT_CONFIG_OPTION_POSTSCRIPT_NAMES */ /*************************************************************************/ /* */ /* Define TT_CONFIG_OPTION_SFNT_NAMES if your applications need to */ /* access the internal name table in a SFNT-based format like TrueType */ /* or OpenType. The name table contains various strings used to */ /* describe the font, like family name, copyright, version, etc. It */ /* does not contain any glyph name though. */ /* */ /* Accessing SFNT names is done through the functions declared in */ /* `freetype/ftnames.h'. */ /* */ /* #define TT_CONFIG_OPTION_SFNT_NAMES */ /*************************************************************************/ /* */ /* TrueType CMap support */ /* */ /* Here you can fine-tune which TrueType CMap table format shall be */ /* supported. */ #define TT_CONFIG_CMAP_FORMAT_0 #define TT_CONFIG_CMAP_FORMAT_2 #define TT_CONFIG_CMAP_FORMAT_4 #define TT_CONFIG_CMAP_FORMAT_6 #define TT_CONFIG_CMAP_FORMAT_8 #define TT_CONFIG_CMAP_FORMAT_10 #define TT_CONFIG_CMAP_FORMAT_12 /*************************************************************************/ /*************************************************************************/ /**** ****/ /**** T R U E T Y P E D R I V E R C O N F I G U R A T I O N ****/ /**** ****/ /*************************************************************************/ /*************************************************************************/ /*************************************************************************/ /* */ /* Define TT_CONFIG_OPTION_BYTECODE_INTERPRETER if you want to compile */ /* a bytecode interpreter in the TrueType driver. Note that there are */ /* important patent issues related to the use of the interpreter. */ /* */ /* By undefining this, you will only compile the code necessary to load */ /* TrueType glyphs without hinting. */ /* */ /* Do not #undef this macro here, since the build system might */ /* define it for certain configurations only. */ /* */ /* #define TT_CONFIG_OPTION_BYTECODE_INTERPRETER */ /*************************************************************************/ /* */ /* Define TT_CONFIG_OPTION_UNPATENTED_HINTING (in addition to */ /* TT_CONFIG_OPTION_BYTECODE_INTERPRETER) to compile the unpatented */ /* work-around hinting system. Note that for the moment, the algorithm */ /* is only used when selected at runtime through the parameter tag */ /* FT_PARAM_TAG_UNPATENTED_HINTING; or when the debug hook */ /* FT_DEBUG_HOOK_UNPATENTED_HINTING is globally activated. */ /* */ #define TT_CONFIG_OPTION_UNPATENTED_HINTING /*************************************************************************/ /* */ /* Define TT_CONFIG_OPTION_INTERPRETER_SWITCH to compile the TrueType */ /* bytecode interpreter with a huge switch statement, rather than a call */ /* table. This results in smaller and faster code for a number of */ /* architectures. */ /* */ /* Note however that on some compiler/processor combinations, undefining */ /* this macro will generate faster, though larger, code. */ /* */ #define TT_CONFIG_OPTION_INTERPRETER_SWITCH /*************************************************************************/ /* */ /* Define TT_CONFIG_OPTION_COMPONENT_OFFSET_SCALED to compile the */ /* TrueType glyph loader to use Apple's definition of how to handle */ /* component offsets in composite glyphs. */ /* */ /* Apple and MS disagree on the default behavior of component offsets */ /* in composites. Apple says that they should be scaled by the scale */ /* factors in the transformation matrix (roughly, it's more complex) */ /* while MS says they should not. OpenType defines two bits in the */ /* composite flags array which can be used to disambiguate, but old */ /* fonts will not have them. */ /* */ /* http://partners.adobe.com/asn/developer/opentype/glyf.html */ /* http://fonts.apple.com/TTRefMan/RM06/Chap6glyf.html */ /* */ #undef TT_CONFIG_OPTION_COMPONENT_OFFSET_SCALED /*************************************************************************/ /* */ /* Define TT_CONFIG_OPTION_GX_VAR_SUPPORT if you want to include */ /* support for Apple's distortable font technology (fvar, gvar, cvar, */ /* and avar tables). This has many similarities to Type 1 Multiple */ /* Masters support. */ /* */ /* #define TT_CONFIG_OPTION_GX_VAR_SUPPORT */ /*************************************************************************/ /*************************************************************************/ /**** ****/ /**** T Y P E 1 D R I V E R C O N F I G U R A T I O N ****/ /**** ****/ /*************************************************************************/ /*************************************************************************/ /*************************************************************************/ /* */ /* T1_MAX_DICT_DEPTH is the maximal depth of nest dictionaries and */ /* arrays in the Type 1 stream (see t1load.c). A minimum of 4 is */ /* required. */ /* */ #define T1_MAX_DICT_DEPTH 5 /*************************************************************************/ /* */ /* T1_MAX_SUBRS_CALLS details the maximum number of nested sub-routine */ /* calls during glyph loading. */ /* */ #define T1_MAX_SUBRS_CALLS 16 /*************************************************************************/ /* */ /* T1_MAX_CHARSTRING_OPERANDS is the charstring stack's capacity. A */ /* minimum of 16 is required. */ /* */ /* The Chinese font MingTiEG-Medium (CNS 11643 character set) needs 256. */ /* */ #define T1_MAX_CHARSTRINGS_OPERANDS 256 /*************************************************************************/ /* */ /* Define this configuration macro if you want to prevent the */ /* compilation of `t1afm', which is in charge of reading Type 1 AFM */ /* files into an existing face. Note that if set, the T1 driver will be */ /* unable to produce kerning distances. */ /* */ #undef T1_CONFIG_OPTION_NO_AFM /*************************************************************************/ /* */ /* Define this configuration macro if you want to prevent the */ /* compilation of the Multiple Masters font support in the Type 1 */ /* driver. */ /* */ #undef T1_CONFIG_OPTION_NO_MM_SUPPORT /* */ /* * This temporary macro is used to control various optimizations for * reducing the heap footprint of memory-mapped TrueType files. * */ #define FT_OPTIMIZE_MEMORY FT_END_HEADER #endif /* __FTOPTION_H__ */ /* END */ --- NEW FILE: ftmodule.h --- //FT_USE_MODULE(autofit_module_class) FT_USE_MODULE(tt_driver_class) FT_USE_MODULE(t1_driver_class) //FT_USE_MODULE(cff_driver_class) //FT_USE_MODULE(t1cid_driver_class) //FT_USE_MODULE(pfr_driver_class) //FT_USE_MODULE(t42_driver_class) //FT_USE_MODULE(winfnt_driver_class) //FT_USE_MODULE(pcf_driver_class) FT_USE_MODULE(psaux_module_class) FT_USE_MODULE(psnames_module_class) FT_USE_MODULE(pshinter_module_class) //FT_USE_MODULE(ft_raster1_renderer_class) //FT_USE_MODULE(sfnt_module_class) //FT_USE_MODULE(ft_smooth_renderer_class) //FT_USE_MODULE(ft_smooth_lcd_renderer_class) //FT_USE_MODULE(ft_smooth_lcdv_renderer_class) //FT_USE_MODULE(otv_module_class) FT_USE_MODULE(bdf_driver_class) --- NEW FILE: ftconfig.h --- /***************************************************************************/ /* */ /* ftconfig.h */ /* */ /* ANSI-specific configuration file (specification only). */ /* */ /* Copyright 1996-2001, 2002, 2003, 2004 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. */ /* */ /***************************************************************************/ /*************************************************************************/ /* */ /* This header file contains a number of macro definitions that are used */ /* by the rest of the engine. Most of the macros here are automatically */ /* determined at compile time, and you should not need to change it to */ /* port FreeType, except to compile the library with a non-ANSI */ /* compiler. */ /* */ /* Note however that if some specific modifications are needed, we */ /* advise you to place a modified copy in your build directory. */ /* */ /* The build directory is usually `freetype/builds/<system>', and */ /* contains system-specific files that are always included first when */ /* building the library. */ /* */ /* This ANSI version should stay in `include/freetype/config'. */ /* */ /*************************************************************************/ #ifndef __FTCONFIG_H__ #define __FTCONFIG_H__ #include <ft2build.h> #include FT_CONFIG_OPTIONS_H #include FT_CONFIG_STANDARD_LIBRARY_H FT_BEGIN_HEADER /*************************************************************************/ /* */ /* PLATFORM-SPECIFIC CONFIGURATION MACROS */ /* */ /* These macros can be toggled to suit a specific system. The current */ /* ones are defaults used to compile FreeType in an ANSI C environment */ /* (16bit compilers are also supported). Copy this file to your own */ /* `freetype/builds/<system>' directory, and edit it to port the engine. */ /* */ /*************************************************************************/ /* There are systems (like the Texas Instruments 'C54x) where a `char' */ /* has 16 bits. ANSI C says that sizeof(char) is always 1. Since an */ /* `int' has 16 bits also for this system, sizeof(int) gives 1 which */ /* is probably unexpected. */ /* */ /* `CHAR_BIT' (defined in limits.h) gives the number of bits in a */ /* `char' type. */ #ifndef FT_CHAR_BIT #define FT_CHAR_BIT CHAR_BIT #endif /* The size of an `int' type. */ #if FT_UINT_MAX == 0xFFFFUL #define FT_SIZEOF_INT (16 / FT_CHAR_BIT) #elif FT_UINT_MAX == 0xFFFFFFFFUL #define FT_SIZEOF_INT (32 / FT_CHAR_BIT) #elif FT_UINT_MAX > 0xFFFFFFFFUL && FT_UINT_MAX == 0xFFFFFFFFFFFFFFFFUL #define FT_SIZEOF_INT (64 / FT_CHAR_BIT) #else #error "Unsupported size of `int' type!" #endif /* The size of a `long' type. A five-byte `long' (as used e.g. on the */ /* DM642) is recognized but avoided. */ #if FT_ULONG_MAX == 0xFFFFFFFFUL #define FT_SIZEOF_LONG (32 / FT_CHAR_BIT) #elif FT_ULONG_MAX > 0xFFFFFFFFUL && FT_ULONG_MAX == 0xFFFFFFFFFFUL #define FT_SIZEOF_LONG (32 / FT_CHAR_BIT) #elif FT_ULONG_MAX > 0xFFFFFFFFUL && FT_ULONG_MAX == 0xFFFFFFFFFFFFFFFFUL #define FT_SIZEOF_LONG (64 / FT_CHAR_BIT) #else #error "Unsupported size of `long' type!" #endif /* Preferred alignment of data */ #define FT_ALIGNMENT 8 /* FT_UNUSED is a macro used to indicate that a given parameter is not */ /* used -- this is only used to get rid of unpleasant compiler warnings */ #ifndef FT_UNUSED #define FT_UNUSED( arg ) ( (arg) = (arg) ) #endif /*************************************************************************/ /* */ /* AUTOMATIC CONFIGURATION MACROS */ /* */ /* These macros are computed from the ones defined above. Don't touch */ /* their definition, unless you know precisely what you are doing. No */ /* porter should need to mess with them. */ /* */ /*************************************************************************/ /*************************************************************************/ /* */ /* Mac support */ /* */ /* This is the only necessary change, so it is defined here instead */ /* providing a new configuration file. */ /* */ #if ( defined( __APPLE__ ) && !defined( DARWIN_NO_CARBON ) ) || \ ( defined( __MWERKS__ ) && defined( macintosh ) ) #define FT_MACINTOSH 1 #endif /*************************************************************************/ /* */ /* IntN types */ /* */ /* Used to guarantee the size of some specific integers. */ /* */ typedef signed short FT_Int16; typedef unsigned short FT_UInt16; #if FT_SIZEOF_INT == (32 / FT_CHAR_BIT) typedef signed int FT_Int32; typedef unsigned int FT_UInt32; #elif FT_SIZEOF_LONG == (32 / FT_CHAR_BIT) typedef signed long FT_Int32; typedef unsigned long FT_UInt32; #else #error "no 32bit type found -- please check your configuration files" #endif /* look up an integer type that is at least 32 bits */ #if FT_SIZEOF_INT >= (32 / FT_CHAR_BIT) typedef int FT_Fast; typedef unsigned int FT_UFast; #elif FT_SIZEOF_LONG >= (32 / FT_CHAR_BIT) typedef long FT_Fast; typedef unsigned long FT_UFast; #endif /* determine whether we have a 64-bit int type for platforms without */ /* Autoconf */ #if FT_SIZEOF_LONG == (64 / FT_CHAR_BIT) /* FT_LONG64 must be defined if a 64-bit type is available */ #define FT_LONG64 #define FT_INT64 long #elif defined( _MSC_VER ) && _MSC_VER >= 900 /* Visual C++ (and Intel C++) */ /* this compiler provides the __int64 type */ #define FT_LONG64 #define FT_INT64 __int64 #elif defined( __BORLANDC__ ) /* Borland C++ */ /* XXXX: We should probably check the value of __BORLANDC__ in order */ /* to test the compiler version. */ /* this compiler provides the __int64 type */ #define FT_LONG64 #define FT_INT64 __int64 #elif defined( __WATCOMC__ ) /* Watcom C++ */ /* Watcom doesn't provide 64-bit data types */ #elif defined( __MWERKS__ ) /* Metrowerks CodeWarrior */ #define FT_LONG64 #define FT_INT64 long long int #elif defined( __GNUC__ ) /* GCC provides the "long long" type */ #define FT_LONG64 #define FT_INT64 long long int #endif /* FT_SIZEOF_LONG == (64 / FT_CHAR_BIT) */ #define FT_BEGIN_STMNT do { #define FT_END_STMNT } while ( 0 ) #define FT_DUMMY_STMNT FT_BEGIN_STMNT FT_END_STMNT /*************************************************************************/ /* */ /* A 64-bit data type will create compilation problems if you compile */ /* in strict ANSI mode. To avoid them, we disable their use if */ /* __STDC__ is defined. You can however ignore this rule by */ /* defining the FT_CONFIG_OPTION_FORCE_INT64 configuration macro. */ /* */ #if defined( FT_LONG64 ) && !defined( FT_CONFIG_OPTION_FORCE_INT64 ) #ifdef __STDC__ /* undefine the 64-bit macros in strict ANSI compilation mode */ #undef FT_LONG64 #undef FT_INT64 #endif /* __STDC__ */ #endif /* FT_LONG64 && !FT_CONFIG_OPTION_FORCE_INT64 */ #ifdef FT_MAKE_OPTION_SINGLE_OBJECT #define FT_LOCAL( x ) static x #define FT_LOCAL_DEF( x ) static x #else #ifdef __cplusplus #define FT_LOCAL( x ) extern "C" x #define FT_LOCAL_DEF( x ) extern "C" x #else #define FT_LOCAL( x ) extern x #define FT_LOCAL_DEF( x ) x #endif #endif /* FT_MAKE_OPTION_SINGLE_OBJECT */ #ifndef FT_BASE #ifdef __cplusplus #define FT_BASE( x ) extern "C" x #else #define FT_BASE( x ) extern x #endif #endif /* !FT_BASE */ #ifndef FT_BASE_DEF #ifdef __cplusplus #define FT_BASE_DEF( x ) extern "C" x #else #define FT_BASE_DEF( x ) extern x #endif #endif /* !FT_BASE_DEF */ #ifndef FT_EXPORT #ifdef __cplusplus #define FT_EXPORT( x ) extern "C" x #else #define FT_EXPORT( x ) extern x #endif #endif /* !FT_EXPORT */ #ifndef FT_EXPORT_DEF #ifdef __cplusplus #define FT_EXPORT_DEF( x ) extern "C" x #else #define FT_EXPORT_DEF( x ) extern x #endif #endif /* !FT_EXPORT_DEF */ #ifndef FT_EXPORT_VAR #ifdef __cplusplus #define FT_EXPORT_VAR( x ) extern "C" x #else #define FT_EXPORT_VAR( x ) extern x #endif #endif /* !FT_EXPORT_VAR */ /* The following macros are needed to compile the library with a */ /* C++ compiler and with 16bit compilers. */ /* */ /* This is special. Within C++, you must specify `extern "C"' for */ /* functions which are used via function pointers, and you also */ /* must do that for structures which contain function pointers to */ /* assure C linkage -- it's not possible to have (local) anonymous */ /* functions which are accessed by (global) function pointers. */ /* */ /* */ /* FT_CALLBACK_DEF is used to _define_ a callback function. */ /* */ /* FT_CALLBACK_TABLE is used to _declare_ a constant variable that */ /* contains pointers to callback functions. */ /* */ /* FT_CALLBACK_TABLE_DEF is used to _define_ a constant variable */ /* that contains pointers to callback functions. */ /* */ /* */ /* Some 16bit compilers have to redefine these macros to insert */ /* the infamous `_cdecl' or `__fastcall' declarations. */ /* */ #ifndef FT_CALLBACK_DEF #ifdef __cplusplus #define FT_CALLBACK_DEF( x ) extern "C" x #else #define FT_CALLBACK_DEF( x ) static x #endif #endif /* FT_CALLBACK_DEF */ #ifndef FT_CALLBACK_TABLE #ifdef __cplusplus #define FT_CALLBACK_TABLE extern "C" #define FT_CALLBACK_TABLE_DEF extern "C" #else #define FT_CALLBACK_TABLE extern #define FT_CALLBACK_TABLE_DEF /* nothing */ #endif #endif /* FT_CALLBACK_TABLE */ FT_END_HEADER #endif /* __FTCONFIG_H__ */ /* END */ --- NEW FILE: ftheader.h --- /***************************************************************************/ /* */ /* ftheader.h */ /* */ /* Build macros of the FreeType 2 library. */ /* */ /* Copyright 1996-2001, 2002, 2003, 2004 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. */ /* */ /***************************************************************************/ #ifndef __FT_HEADER_H__ #define __FT_HEADER_H__ /*@***********************************************************************/ /* */ /* <Macro> */ /* FT_BEGIN_HEADER */ /* */ /* <Description> */ /* This macro is used in association with @FT_END_HEADER in header */ /* files to ensure that the declarations within are properly */ /* encapsulated in an `extern "C" { .. }' block when included from a */ /* C++ compiler. */ /* */ #ifdef __cplusplus #define FT_BEGIN_HEADER extern "C" { #else #define FT_BEGIN_HEADER /* nothing */ #endif /*@***********************************************************************/ /* */ /* <Macro> */ /* FT_END_HEADER */ /* */ /* <Description> */ /* This macro is used in association with @FT_BEGIN_HEADER in header */ /* files to ensure that the declarations within are properly */ /* encapsulated in an `extern "C" { .. }' block when included from a */ /* C++ compiler. */ /* */ #ifdef __cplusplus #define FT_END_HEADER } #else #define FT_END_HEADER /* nothing */ #endif /*************************************************************************/ /* */ /* Aliases for the FreeType 2 public and configuration files. */ /* */ /*************************************************************************/ /*************************************************************************/ /* */ /* <Section> */ /* header_file_macros */ /* */ /* <Title> */ /* Header File Macros */ /* */ /* <Abstract> */ /* Macro definitions used to #include specific header files. */ /* */ /* <Description> */ /* The following macros are defined to the name of specific */ /* FreeType 2 header files. They can be used directly in #include */ /* statements as in: */ /* */ /* { */ /* #include FT_FREETYPE_H */ /* #include FT_MULTIPLE_MASTERS_H */ /* #include FT_GLYPH_H */ /* } */ /* */ /* There are several reasons why we are now using macros to name */ /* public header files. The first one is that such macros are not */ /* limited to the infamous 8.3 naming rule required by DOS (and */ /* `FT_MULTIPLE_MASTERS_H' is a lot more meaningful than `ftmm.h'). */ /* */ /* The second reason is that is allows for more flexibility in the */ /* way FreeType 2 is installed on a given system. */ /* */ /*************************************************************************/ /* configuration files */ /*************************************************************************/ /* */ /* @macro: */ /* FT_CONFIG_CONFIG_H */ /* */ /* @description: */ /* A macro used in #include statements to name the file containing */ /* FreeType 2 configuration data. */ /* */ #ifndef FT_CONFIG_CONFIG_H #define FT_CONFIG_CONFIG_H <freetype/config/ftconfig.h> #endif /*************************************************************************/ /* */ /* @macro: */ /* FT_CONFIG_STANDARD_LIBRARY_H */ /* */ /* @description: */ /* A macro used in #include statements to name the file containing */ /* FreeType 2 configuration data. */ /* */ #ifndef FT_CONFIG_STANDARD_LIBRARY_H #define FT_CONFIG_STANDARD_LIBRARY_H <freetype/config/ftstdlib.h> #endif /*************************************************************************/ /* */ /* @macro: */ /* FT_CONFIG_OPTIONS_H */ /* */ /* @description: */ /* A macro used in #include statements to name the file containing */ /* FreeType 2 project-specific configuration options. */ /* */ #ifndef FT_CONFIG_OPTIONS_H #define FT_CONFIG_OPTIONS_H <freetype/config/ftoption.h> #endif /*************************************************************************/ /* */ /* @macro: */ /* FT_CONFIG_MODULES_H */ /* */ /* @description: */ /* A macro used in #include statements to name the file containing */ /* the list of FreeType 2 modules that are statically linked to new */ /* library instances in @FT_Init_FreeType. */ /* */ #ifndef FT_CONFIG_MODULES_H #define FT_CONFIG_MODULES_H <freetype/config/ftmodule.h> #endif /* public headers */ /*************************************************************************/ /* */ /* @macro: */ /* FT_FREETYPE_H */ /* */ /* @description: */ /* A macro used in #include statements to name the file containing */ /* the base FreeType 2 API. */ /* */ #define FT_FREETYPE_H <freetype/freetype.h> /*************************************************************************/ /* */ /* @macro: */ /* FT_ERRORS_H */ /* */ /* @description: */ /* A macro used in #include statements to name the file containing */ /* the list of FreeType 2 error codes (and messages). */ /* ... [truncated message content] |
|
From: Ehud S. <esh...@us...> - 2006-04-21 16:22:38
|
Update of /cvsroot/roadmap/roadmap_editor/src/freetype/src/bdf In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv22848/src/bdf Added Files: bdf.c bdfdrivr.c bdflib.c Log Message: Import freetype sources. --- NEW FILE: bdflib.c --- /* * Copyright 2000 Computing Research Labs, New Mexico State University * Copyright 2001, 2002, 2003, 2004, 2005 Francesco Zappa Nardelli * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE COMPUTING RESEARCH LAB OR NEW MEXICO STATE UNIVERSITY BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT [...2379 lines suppressed...] } FT_LOCAL_DEF( bdf_property_t * ) bdf_get_font_property( bdf_font_t* font, const char* name ) { hashnode hn; if ( font == 0 || font->props_size == 0 || name == 0 || *name == 0 ) return 0; hn = hash_lookup( name, (hashtable *)font->internal ); return hn ? ( font->props + (unsigned long)hn->data ) : 0; } /* END */ --- NEW FILE: bdfdrivr.c --- /* bdfdrivr.c FreeType font driver for bdf files Copyright (C) 2001, 2002, 2003, 2004, 2005 by Francesco Zappa Nardelli Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include <ft2build.h> #include FT_INTERNAL_DEBUG_H #include FT_INTERNAL_STREAM_H #include FT_INTERNAL_OBJECTS_H #include FT_BDF_H #include FT_SERVICE_BDF_H #include FT_SERVICE_XFREE86_NAME_H #include "bdf.h" #include "bdfdrivr.h" #include "bdferror.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_bdfdriver typedef struct BDF_CMapRec_ { FT_CMapRec cmap; FT_UInt num_encodings; BDF_encoding_el* encodings; } BDF_CMapRec, *BDF_CMap; FT_CALLBACK_DEF( FT_Error ) bdf_cmap_init( FT_CMap bdfcmap, FT_Pointer init_data ) { BDF_CMap cmap = (BDF_CMap)bdfcmap; BDF_Face face = (BDF_Face)FT_CMAP_FACE( cmap ); FT_UNUSED( init_data ); cmap->num_encodings = face->bdffont->glyphs_used; cmap->encodings = face->en_table; return BDF_Err_Ok; } FT_CALLBACK_DEF( void ) bdf_cmap_done( FT_CMap bdfcmap ) { BDF_CMap cmap = (BDF_CMap)bdfcmap; cmap->encodings = NULL; cmap->num_encodings = 0; } FT_CALLBACK_DEF( FT_UInt ) bdf_cmap_char_index( FT_CMap bdfcmap, FT_UInt32 charcode ) { BDF_CMap cmap = (BDF_CMap)bdfcmap; BDF_encoding_el* encodings = cmap->encodings; FT_UInt min, max, mid; FT_UInt result = 0; min = 0; max = cmap->num_encodings; while ( min < max ) { FT_UInt32 code; mid = ( min + max ) >> 1; code = encodings[mid].enc; if ( charcode == code ) { /* increase glyph index by 1 -- */ /* we reserve slot 0 for the undefined glyph */ result = encodings[mid].glyph + 1; break; } if ( charcode < code ) max = mid; else min = mid + 1; } return result; } FT_CALLBACK_DEF( FT_UInt ) bdf_cmap_char_next( FT_CMap bdfcmap, FT_UInt32 *acharcode ) { BDF_CMap cmap = (BDF_CMap)bdfcmap; BDF_encoding_el* encodings = cmap->encodings; FT_UInt min, max, mid; FT_UInt32 charcode = *acharcode + 1; FT_UInt result = 0; min = 0; max = cmap->num_encodings; while ( min < max ) { FT_UInt32 code; mid = ( min + max ) >> 1; code = encodings[mid].enc; if ( charcode == code ) { /* increase glyph index by 1 -- */ /* we reserve slot 0 for the undefined glyph */ result = encodings[mid].glyph + 1; goto Exit; } if ( charcode < code ) max = mid; else min = mid + 1; } charcode = 0; if ( min < cmap->num_encodings ) { charcode = encodings[min].enc; result = encodings[min].glyph + 1; } Exit: *acharcode = charcode; return result; } FT_CALLBACK_TABLE_DEF const FT_CMap_ClassRec bdf_cmap_class = { sizeof ( BDF_CMapRec ), bdf_cmap_init, bdf_cmap_done, bdf_cmap_char_index, bdf_cmap_char_next }; static FT_Error bdf_interpret_style( BDF_Face bdf ) { FT_Error error = BDF_Err_Ok; FT_Face face = FT_FACE( bdf ); FT_Memory memory = face->memory; bdf_font_t* font = bdf->bdffont; bdf_property_t* prop; char *istr = NULL, *bstr = NULL; char *sstr = NULL, *astr = NULL; int parts = 0, len = 0; face->style_flags = 0; prop = bdf_get_font_property( font, (char *)"SLANT" ); if ( prop && prop->format == BDF_ATOM && prop->value.atom && ( *(prop->value.atom) == 'O' || *(prop->value.atom) == 'o' || *(prop->value.atom) == 'I' || *(prop->value.atom) == 'i' ) ) { face->style_flags |= FT_STYLE_FLAG_ITALIC; istr = ( *(prop->value.atom) == 'O' || *(prop->value.atom) == 'o' ) ? (char *)"Oblique" : (char *)"Italic"; len += ft_strlen( istr ); parts++; } prop = bdf_get_font_property( font, (char *)"WEIGHT_NAME" ); if ( prop && prop->format == BDF_ATOM && prop->value.atom && ( *(prop->value.atom) == 'B' || *(prop->value.atom) == 'b' ) ) { face->style_flags |= FT_STYLE_FLAG_BOLD; bstr = (char *)"Bold"; len += ft_strlen( bstr ); parts++; } prop = bdf_get_font_property( font, (char *)"SETWIDTH_NAME" ); if ( prop && prop->format == BDF_ATOM && prop->value.atom && *(prop->value.atom) && !( *(prop->value.atom) == 'N' || *(prop->value.atom) == 'n' ) ) { sstr = (char *)(prop->value.atom); len += ft_strlen( sstr ); parts++; } prop = bdf_get_font_property( font, (char *)"ADD_STYLE_NAME" ); if ( prop && prop->format == BDF_ATOM && prop->value.atom && *(prop->value.atom) && !( *(prop->value.atom) == 'N' || *(prop->value.atom) == 'n' ) ) { astr = (char *)(prop->value.atom); len += ft_strlen( astr ); parts++; } if ( !parts || !len ) face->style_name = (char *)"Regular"; else { char *style, *s; unsigned int i; if ( FT_ALLOC( style, len + parts ) ) return error; s = style; if ( astr ) { ft_strcpy( s, astr ); for ( i = 0; i < ft_strlen( astr ); i++, s++ ) if ( *s == ' ' ) *s = '-'; /* replace spaces with dashes */ *(s++) = ' '; } if ( bstr ) { ft_strcpy( s, bstr ); s += ft_strlen( bstr ); *(s++) = ' '; } if ( istr ) { ft_strcpy( s, istr ); s += ft_strlen( istr ); *(s++) = ' '; } if ( sstr ) { ft_strcpy( s, sstr ); for ( i = 0; i < ft_strlen( sstr ); i++, s++ ) if ( *s == ' ' ) *s = '-'; /* replace spaces with dashes */ *(s++) = ' '; } *(--s) = '\0'; /* overwrite last ' ', terminate the string */ face->style_name = style; /* allocated string */ } return error; } FT_CALLBACK_DEF( void ) BDF_Face_Done( FT_Face bdfface ) /* BDF_Face */ { BDF_Face face = (BDF_Face)bdfface; FT_Memory memory = FT_FACE_MEMORY( face ); bdf_free_font( face->bdffont ); FT_FREE( face->en_table ); FT_FREE( face->charset_encoding ); FT_FREE( face->charset_registry ); FT_FREE( bdfface->family_name ); FT_FREE( bdfface->available_sizes ); FT_FREE( face->bdffont ); FT_TRACE4(( "BDF_Face_Done: done face\n" )); } FT_CALLBACK_DEF( FT_Error ) BDF_Face_Init( FT_Stream stream, FT_Face bdfface, /* BDF_Face */ FT_Int face_index, FT_Int num_params, FT_Parameter* params ) { FT_Error error = BDF_Err_Ok; BDF_Face face = (BDF_Face)bdfface; FT_Memory memory = FT_FACE_MEMORY( face ); bdf_font_t* font; bdf_options_t options; FT_UNUSED( num_params ); FT_UNUSED( params ); FT_UNUSED( face_index ); if ( FT_STREAM_SEEK( 0 ) ) goto Exit; options.correct_metrics = 1; /* FZ XXX: options semantics */ options.keep_unencoded = 1; options.keep_comments = 0; options.font_spacing = BDF_PROPORTIONAL; error = bdf_load_font( stream, memory, &options, &font ); if ( error == BDF_Err_Missing_Startfont_Field ) { FT_TRACE2(( "[not a valid BDF file]\n" )); goto Fail; } else if ( error ) goto Exit; /* we have a bdf font: let's construct the face object */ face->bdffont = font; { bdf_property_t* prop = NULL; FT_TRACE4(( "number of glyphs: %d (%d)\n", font->glyphs_size, font->glyphs_used )); FT_TRACE4(( "number of unencoded glyphs: %d (%d)\n", font->unencoded_size, font->unencoded_used )); bdfface->num_faces = 1; bdfface->face_index = 0; bdfface->face_flags = FT_FACE_FLAG_FIXED_SIZES | FT_FACE_FLAG_HORIZONTAL | FT_FACE_FLAG_FAST_GLYPHS; prop = bdf_get_font_property( font, "SPACING" ); if ( prop && prop->format == BDF_ATOM && prop->value.atom && ( *(prop->value.atom) == 'M' || *(prop->value.atom) == 'm' || *(prop->value.atom) == 'C' || *(prop->value.atom) == 'c' ) ) bdfface->face_flags |= FT_FACE_FLAG_FIXED_WIDTH; /* FZ XXX: TO DO: FT_FACE_FLAGS_VERTICAL */ /* FZ XXX: I need a font to implement this */ prop = bdf_get_font_property( font, "FAMILY_NAME" ); if ( prop && prop->value.atom ) { int l = ft_strlen( prop->value.atom ) + 1; if ( FT_NEW_ARRAY( bdfface->family_name, l ) ) goto Exit; ft_strcpy( bdfface->family_name, prop->value.atom ); } else bdfface->family_name = 0; if ( ( error = bdf_interpret_style( face ) ) != 0 ) goto Exit; /* the number of glyphs (with one slot for the undefined glyph */ /* at position 0 and all unencoded glyphs) */ bdfface->num_glyphs = font->glyphs_size + 1; bdfface->num_fixed_sizes = 1; if ( FT_NEW_ARRAY( bdfface->available_sizes, 1 ) ) goto Exit; { FT_Bitmap_Size* bsize = bdfface->available_sizes; FT_Short resolution_x = 0, resolution_y = 0; FT_MEM_ZERO( bsize, sizeof ( FT_Bitmap_Size ) ); bsize->height = (FT_Short)( font->font_ascent + font->font_descent ); prop = bdf_get_font_property( font, "AVERAGE_WIDTH" ); if ( prop ) bsize->width = (FT_Short)( ( prop->value.int32 + 5 ) / 10 ); else bsize->width = (FT_Short)( bsize->height * 2/3 ); prop = bdf_get_font_property( font, "POINT_SIZE" ); if ( prop ) /* convert from 722.7 decipoints to 72 points per inch */ bsize->size = (FT_Pos)( ( prop->value.int32 * 64 * 7200 + 36135L ) / 72270L ); prop = bdf_get_font_property( font, "PIXEL_SIZE" ); if ( prop ) bsize->y_ppem = (FT_Short)prop->value.int32 << 6; prop = bdf_get_font_property( font, "RESOLUTION_X" ); if ( prop ) resolution_x = (FT_Short)prop->value.int32; prop = bdf_get_font_property( font, "RESOLUTION_Y" ); if ( prop ) resolution_y = (FT_Short)prop->value.int32; if ( bsize->y_ppem == 0 ) { bsize->y_ppem = bsize->size; if ( resolution_y ) bsize->y_ppem = bsize->y_ppem * resolution_y / 72; } if ( resolution_x && resolution_y ) bsize->x_ppem = bsize->y_ppem * resolution_x / resolution_y; else bsize->x_ppem = bsize->y_ppem; } /* encoding table */ { bdf_glyph_t* cur = font->glyphs; unsigned long n; if ( FT_NEW_ARRAY( face->en_table, font->glyphs_size ) ) goto Exit; face->default_glyph = 0; for ( n = 0; n < font->glyphs_size; n++ ) { (face->en_table[n]).enc = cur[n].encoding; FT_TRACE4(( "idx %d, val 0x%lX\n", n, cur[n].encoding )); (face->en_table[n]).glyph = (FT_Short)n; if ( cur[n].encoding == font->default_char ) face->default_glyph = n; } } /* charmaps */ { bdf_property_t *charset_registry = 0, *charset_encoding = 0; FT_Bool unicode_charmap = 0; charset_registry = bdf_get_font_property( font, "CHARSET_REGISTRY" ); charset_encoding = bdf_get_font_property( font, "CHARSET_ENCODING" ); if ( charset_registry && charset_encoding ) { if ( charset_registry->format == BDF_ATOM && charset_encoding->format == BDF_ATOM && charset_registry->value.atom && charset_encoding->value.atom ) { const char* s; if ( FT_NEW_ARRAY( face->charset_encoding, ft_strlen( charset_encoding->value.atom ) + 1 ) ) goto Exit; if ( FT_NEW_ARRAY( face->charset_registry, ft_strlen( charset_registry->value.atom ) + 1 ) ) goto Exit; ft_strcpy( face->charset_registry, charset_registry->value.atom ); ft_strcpy( face->charset_encoding, charset_encoding->value.atom ); /* Uh, oh, compare first letters manually to avoid dependency on locales. */ s = face->charset_registry; if ( ( s[0] == 'i' || s[0] == 'I' ) && ( s[1] == 's' || s[1] == 'S' ) && ( s[2] == 'o' || s[2] == 'O' ) ) { s += 3; if ( !ft_strcmp( s, "10646" ) || ( !ft_strcmp( s, "8859" ) && !ft_strcmp( face->charset_encoding, "1" ) ) ) unicode_charmap = 1; } { FT_CharMapRec charmap; charmap.face = FT_FACE( face ); charmap.encoding = FT_ENCODING_NONE; charmap.platform_id = 0; charmap.encoding_id = 0; if ( unicode_charmap ) { charmap.encoding = FT_ENCODING_UNICODE; charmap.platform_id = 3; charmap.encoding_id = 1; } error = FT_CMap_New( &bdf_cmap_class, NULL, &charmap, NULL ); #if 0 /* Select default charmap */ if ( bdfface->num_charmaps ) bdfface->charmap = bdfface->charmaps[0]; #endif } goto Exit; } } /* otherwise assume Adobe standard encoding */ { FT_CharMapRec charmap; charmap.face = FT_FACE( face ); charmap.encoding = FT_ENCODING_ADOBE_STANDARD; charmap.platform_id = 7; charmap.encoding_id = 0; error = FT_CMap_New( &bdf_cmap_class, NULL, &charmap, NULL ); /* Select default charmap */ if ( bdfface->num_charmaps ) bdfface->charmap = bdfface->charmaps[0]; } } } Exit: return error; Fail: BDF_Face_Done( bdfface ); return BDF_Err_Unknown_File_Format; } FT_CALLBACK_DEF( FT_Error ) BDF_Set_Pixel_Size( FT_Size size, FT_UInt char_width, FT_UInt char_height ) { BDF_Face face = (BDF_Face)FT_SIZE_FACE( size ); FT_Face root = FT_FACE( face ); FT_UNUSED( char_width ); if ( char_height == (FT_UInt)root->available_sizes->height ) { size->metrics.ascender = face->bdffont->font_ascent << 6; size->metrics.descender = -face->bdffont->font_descent << 6; size->metrics.height = ( face->bdffont->font_ascent + face->bdffont->font_descent ) << 6; size->metrics.max_advance = face->bdffont->bbx.width << 6; return BDF_Err_Ok; } else return BDF_Err_Invalid_Pixel_Size; } FT_CALLBACK_DEF( FT_Error ) BDF_Set_Point_Size( FT_Size size, FT_F26Dot6 char_width, FT_F26Dot6 char_height, FT_UInt horz_resolution, FT_UInt vert_resolution ) { BDF_Face face = (BDF_Face)FT_SIZE_FACE( size ); FT_Face root = FT_FACE( face ); FT_UNUSED( char_width ); FT_UNUSED( char_height ); FT_UNUSED( horz_resolution ); FT_UNUSED( vert_resolution ); FT_TRACE4(( "rec %d - pres %d\n", size->metrics.y_ppem, root->available_sizes->y_ppem )); if ( size->metrics.y_ppem == root->available_sizes->y_ppem >> 6 ) { size->metrics.ascender = face->bdffont->font_ascent << 6; size->metrics.descender = -face->bdffont->font_descent << 6; size->metrics.height = ( face->bdffont->font_ascent + face->bdffont->font_descent ) << 6; size->metrics.max_advance = face->bdffont->bbx.width << 6; return BDF_Err_Ok; } else return BDF_Err_Invalid_Pixel_Size; } FT_CALLBACK_DEF( FT_Error ) BDF_Glyph_Load( FT_GlyphSlot slot, FT_Size size, FT_UInt glyph_index, FT_Int32 load_flags ) { BDF_Face face = (BDF_Face)FT_SIZE_FACE( size ); FT_Error error = BDF_Err_Ok; FT_Bitmap* bitmap = &slot->bitmap; bdf_glyph_t glyph; int bpp = face->bdffont->bpp; FT_UNUSED( load_flags ); if ( !face ) { error = BDF_Err_Invalid_Argument; goto Exit; } /* index 0 is the undefined glyph */ if ( glyph_index == 0 ) glyph_index = face->default_glyph; else glyph_index--; /* slot, bitmap => freetype, glyph => bdflib */ glyph = face->bdffont->glyphs[glyph_index]; bitmap->rows = glyph.bbx.height; bitmap->width = glyph.bbx.width; bitmap->pitch = glyph.bpr; /* note: we don't allocate a new array to hold the bitmap; */ /* we can simply point to it */ ft_glyphslot_set_bitmap( slot, glyph.bitmap ); switch ( bpp ) { case 1: bitmap->pixel_mode = FT_PIXEL_MODE_MONO; break; case 2: bitmap->pixel_mode = FT_PIXEL_MODE_GRAY2; break; case 4: bitmap->pixel_mode = FT_PIXEL_MODE_GRAY4; break; case 8: bitmap->pixel_mode = FT_PIXEL_MODE_GRAY; bitmap->num_grays = 256; break; } slot->bitmap_left = glyph.bbx.x_offset; slot->bitmap_top = glyph.bbx.ascent; /* FZ XXX: TODO: vertical metrics */ slot->metrics.horiAdvance = glyph.dwidth << 6; slot->metrics.horiBearingX = glyph.bbx.x_offset << 6; slot->metrics.horiBearingY = glyph.bbx.ascent << 6; slot->metrics.width = bitmap->width << 6; slot->metrics.height = bitmap->rows << 6; slot->linearHoriAdvance = (FT_Fixed)glyph.dwidth << 16; slot->format = FT_GLYPH_FORMAT_BITMAP; Exit: return error; } /* * * BDF SERVICE * */ static FT_Error bdf_get_bdf_property( BDF_Face face, const char* prop_name, BDF_PropertyRec *aproperty ) { bdf_property_t* prop; FT_ASSERT( face && face->bdffont ); prop = bdf_get_font_property( face->bdffont, prop_name ); if ( prop ) { switch ( prop->format ) { case BDF_ATOM: aproperty->type = BDF_PROPERTY_TYPE_ATOM; aproperty->u.atom = prop->value.atom; break; case BDF_INTEGER: aproperty->type = BDF_PROPERTY_TYPE_INTEGER; aproperty->u.integer = prop->value.int32; break; case BDF_CARDINAL: aproperty->type = BDF_PROPERTY_TYPE_CARDINAL; aproperty->u.cardinal = prop->value.card32; break; default: goto Fail; } return 0; } Fail: return BDF_Err_Invalid_Argument; } static FT_Error bdf_get_charset_id( BDF_Face face, const char* *acharset_encoding, const char* *acharset_registry ) { *acharset_encoding = face->charset_encoding; *acharset_registry = face->charset_registry; return 0; } static const FT_Service_BDFRec bdf_service_bdf = { (FT_BDF_GetCharsetIdFunc)bdf_get_charset_id, (FT_BDF_GetPropertyFunc) bdf_get_bdf_property }; /* * * SERVICES LIST * */ static const FT_ServiceDescRec bdf_services[] = { { FT_SERVICE_ID_BDF, &bdf_service_bdf }, { FT_SERVICE_ID_XF86_NAME, FT_XF86_FORMAT_BDF }, { NULL, NULL } }; FT_CALLBACK_DEF( FT_Module_Interface ) bdf_driver_requester( FT_Module module, const char* name ) { FT_UNUSED( module ); return ft_service_list_lookup( bdf_services, name ); } FT_CALLBACK_TABLE_DEF const FT_Driver_ClassRec bdf_driver_class = { { FT_MODULE_FONT_DRIVER | FT_MODULE_DRIVER_NO_OUTLINES, sizeof ( FT_DriverRec ), "bdf", 0x10000L, 0x20000L, 0, (FT_Module_Constructor)0, (FT_Module_Destructor) 0, (FT_Module_Requester) bdf_driver_requester }, sizeof ( BDF_FaceRec ), sizeof ( FT_SizeRec ), sizeof ( FT_GlyphSlotRec ), BDF_Face_Init, BDF_Face_Done, 0, /* FT_Size_InitFunc */ 0, /* FT_Size_DoneFunc */ 0, /* FT_Slot_InitFunc */ 0, /* FT_Slot_DoneFunc */ BDF_Set_Point_Size, BDF_Set_Pixel_Size, BDF_Glyph_Load, 0, /* FT_Face_GetKerningFunc */ 0, /* FT_Face_AttachFunc */ 0, /* FT_Face_GetAdvancesFunc */ }; /* END */ --- NEW FILE: bdf.c --- /* bdf.c FreeType font driver for bdf files Copyright (C) 2001, 2002 by Francesco Zappa Nardelli Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #define FT_MAKE_OPTION_SINGLE_OBJECT #include <ft2build.h> #include "bdflib.c" #include "bdfdrivr.c" /* END */ |
|
From: Ehud S. <esh...@us...> - 2006-04-21 16:22:37
|
Update of /cvsroot/roadmap/roadmap_editor/src/freetype/src/lzw In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv22848/src/lzw Added Files: ftlzw.c zopen.c Log Message: Import freetype sources. --- NEW FILE: zopen.c --- /* $NetBSD: zopen.c,v 1.8 2003/08/07 11:13:29 agc Exp $ */ /*- * Copyright (c) 1985, 1986, 1992, 1993 * The Regents of the University of California. All rights reserved. * * This code is derived from software contributed to Berkeley by * Diomidis Spinellis and James A. Woods, derived from original * work by Spencer Thomas and Joseph Orost. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ /*- * * Copyright (c) 2004, 2005 * Albert Chin-A-Young. * * Modified to work with FreeType's PCF driver. * */ #if defined(LIBC_SCCS) && !defined(lint) #if 0 static char sccsid[] = "@(#)zopen.c 8.1 (Berkeley) 6/27/93"; #else static char rcsid[] = "$NetBSD: zopen.c,v 1.8 2003/08/07 11:13:29 agc Exp $"; #endif #endif /* LIBC_SCCS and not lint */ /*- * fcompress.c - File compression ala IEEE Computer, June 1984. * * Compress authors: * Spencer W. Thomas (decvax!utah-cs!thomas) * Jim McKie (decvax!mcvax!jim) * Steve Davies (decvax!vax135!petsd!peora!srd) * Ken Turkowski (decvax!decwrl!turtlevax!ken) * James A. Woods (decvax!ihnp4!ames!jaw) * Joe Orost (decvax!vax135!petsd!joe) * * Cleaned up and converted to library returning I/O streams by * Diomidis Spinellis <dd...@do...>. */ #include <ctype.h> #if 0 #include <signal.h> #endif #include <stdlib.h> #include <string.h> #if 0 #include <unistd.h> #endif #if 0 static char_type magic_header[] = { 0x1f, 0x9d }; /* 1F 9D */ #endif #define BIT_MASK 0x1f /* Defines for third byte of header. */ #define BLOCK_MASK 0x80 /* * Masks 0x40 and 0x20 are free. I think 0x20 should mean that there is * a fourth header byte (for expansion). */ #define INIT_BITS 9 /* Initial number of bits/code. */ #define MAXCODE(n_bits) ((1 << (n_bits)) - 1) /* Definitions to retain old variable names */ #define fp zs->zs_fp #define state zs->zs_state #define n_bits zs->zs_n_bits #define maxbits zs->zs_maxbits #define maxcode zs->zs_maxcode #define maxmaxcode zs->zs_maxmaxcode #define htab zs->zs_htab #define codetab zs->zs_codetab #define hsize zs->zs_hsize #define free_ent zs->zs_free_ent #define block_compress zs->zs_block_compress #define clear_flg zs->zs_clear_flg #define offset zs->zs_offset #define in_count zs->zs_in_count #define buf_len zs->zs_buf_len #define buf zs->zs_buf #define stackp zs->u.r.zs_stackp #define finchar zs->u.r.zs_finchar #define code zs->u.r.zs_code #define oldcode zs->u.r.zs_oldcode #define incode zs->u.r.zs_incode #define roffset zs->u.r.zs_roffset #define size zs->u.r.zs_size #define gbuf zs->u.r.zs_gbuf /* * To save much memory, we overlay the table used by compress() with those * used by decompress(). The tab_prefix table is the same size and type as * the codetab. The tab_suffix table needs 2**BITS characters. We get this * from the beginning of htab. The output stack uses the rest of htab, and * contains characters. There is plenty of room for any possible stack * (stack used to be 8000 characters). */ #define htabof(i) htab[i] #define codetabof(i) codetab[i] #define tab_prefixof(i) codetabof(i) #define tab_suffixof(i) ((char_type *)(htab))[i] #define de_stack ((char_type *)&tab_suffixof(1 << BITS)) #define CHECK_GAP 10000 /* Ratio check interval. */ /* * the next two codes should not be changed lightly, as they must not * lie within the contiguous general code space. */ #define FIRST 257 /* First free entry. */ #define CLEAR 256 /* Table clear output code. */ /*- * Algorithm from "A Technique for High Performance Data Compression", * Terry A. Welch, IEEE Computer Vol 17, No 6 (June 1984), pp 8-19. * * Algorithm: * Modified Lempel-Ziv method (LZW). Basically finds common * substrings and replaces them with a variable size code. This is * deterministic, and can be done on the fly. Thus, the decompression * procedure needs no input table, but tracks the way the table was built. */ #if 0 static int zclose(s_zstate_t *zs) { free(zs); return (0); } #endif /*- * Output the given code. * Inputs: * code: A n_bits-bit integer. If == -1, then EOF. This assumes * that n_bits =< (long)wordsize - 1. * Outputs: * Outputs code to the file. * Assumptions: * Chars are 8 bits long. * Algorithm: * Maintain a BITS character long buffer (so that 8 codes will * fit in it exactly). Use the VAX insv instruction to insert each * code in turn. When the buffer fills up empty it and start over. */ static const char_type rmask[9] = {0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff}; /* * Decompress read. This routine adapts to the codes in the file building * the "string" table on-the-fly; requiring no table to be stored in the * compressed file. The tables used herein are shared with those of the * compress() routine. See the definitions above. */ static int zread(s_zstate_t *zs) { unsigned int count; if (in_count == 0) return -1; if (zs->avail_out == 0) return 0; count = zs->avail_out; switch (state) { case S_START: state = S_MIDDLE; break; case S_MIDDLE: goto middle; case S_EOF: goto eof; } maxbits = *(zs->next_in); /* Set -b from file. */ zs->avail_in--; zs->next_in++; zs->total_in++; in_count--; block_compress = maxbits & BLOCK_MASK; maxbits &= BIT_MASK; maxmaxcode = 1L << maxbits; if (maxbits > BITS) { return -1; } /* As above, initialize the first 256 entries in the table. */ maxcode = MAXCODE(n_bits = INIT_BITS); for (code = 255; code >= 0; code--) { tab_prefixof(code) = 0; tab_suffixof(code) = (char_type) code; } free_ent = block_compress ? FIRST : 256; finchar = oldcode = getcode(zs); if (oldcode == -1) /* EOF already? */ return 0; /* Get out of here */ /* First code must be 8 bits = char. */ *(zs->next_out)++ = (unsigned char)finchar; zs->total_out++; count--; stackp = de_stack; while ((code = getcode(zs)) > -1) { if ((code == CLEAR) && block_compress) { for (code = 255; code >= 0; code--) tab_prefixof(code) = 0; clear_flg = 1; free_ent = FIRST - 1; if ((code = getcode(zs)) == -1) /* O, untimely death! */ break; } incode = code; /* Special case for KwKwK string. */ if (code >= free_ent) { *stackp++ = (unsigned char)finchar; code = oldcode; } /* Generate output characters in reverse order. */ while (code >= 256) { *stackp++ = tab_suffixof(code); code = tab_prefixof(code); } *stackp++ = (unsigned char)(finchar = tab_suffixof(code)); /* And put them out in forward order. */ middle: if (stackp == de_stack) continue; do { if (count-- == 0) { return zs->avail_out; } *(zs->next_out)++ = *--stackp; zs->total_out++; } while (stackp > de_stack); /* Generate the new entry. */ if ((code = free_ent) < maxmaxcode) { tab_prefixof(code) = (unsigned short)oldcode; tab_suffixof(code) = (unsigned char)finchar; free_ent = code + 1; } /* Remember previous code. */ oldcode = incode; } /* state = S_EOF; */ eof: return (zs->avail_out - count); } /*- * Read one code from the standard input. If EOF, return -1. * Inputs: * stdin * Outputs: * code or -1 is returned. */ static code_int getcode(s_zstate_t *zs) { code_int gcode; int r_off, bits; char_type *bp; bp = gbuf; if (clear_flg > 0 || roffset >= size || free_ent > maxcode) { /* * If the next entry will be too big for the current gcode * size, then we must increase the size. This implies reading * a new buffer full, too. */ if (free_ent > maxcode) { n_bits++; if (n_bits == maxbits) /* Won't get any bigger now. */ maxcode = maxmaxcode; else maxcode = MAXCODE(n_bits); } if (clear_flg > 0) { maxcode = MAXCODE(n_bits = INIT_BITS); clear_flg = 0; } if ( zs->avail_in < (unsigned int)n_bits && in_count > (long)n_bits ) { memcpy (buf, zs->next_in, zs->avail_in); buf_len = (unsigned char)zs->avail_in; zs->avail_in = 0; return -1; } if (buf_len) { memcpy (gbuf, buf, buf_len); memcpy (gbuf + buf_len, zs->next_in, n_bits - buf_len); zs->next_in += n_bits - buf_len; zs->avail_in -= n_bits - buf_len; buf_len = 0; zs->total_in += n_bits; size = n_bits; in_count -= n_bits; } else { if (in_count > n_bits) { memcpy (gbuf, zs->next_in, n_bits); zs->next_in += n_bits; zs->avail_in -= n_bits; zs->total_in += n_bits; size = n_bits; in_count -= n_bits; } else { memcpy (gbuf, zs->next_in, in_count); zs->next_in += in_count; zs->avail_in -= in_count; zs->total_in += in_count; size = in_count; in_count = 0; } } roffset = 0; /* Round size down to integral number of codes. */ size = (size << 3) - (n_bits - 1); } r_off = roffset; bits = n_bits; /* Get to the first byte. */ bp += (r_off >> 3); r_off &= 7; /* Get first part (low order bits). */ gcode = (*bp++ >> r_off); bits -= (8 - r_off); r_off = 8 - r_off; /* Now, roffset into gcode word. */ /* Get any 8 bit parts in the middle (<=1 for up to 16 bits). */ if (bits >= 8) { gcode |= *bp++ << r_off; r_off += 8; bits -= 8; } /* High order bits. */ gcode |= (*bp & rmask[bits]) << r_off; roffset += n_bits; return (gcode); } static void zinit(s_zstate_t *zs) { memset(zs, 0, sizeof (s_zstate_t)); maxbits = BITS; /* User settable max # bits/code. */ maxmaxcode = 1 << maxbits; /* Should NEVER generate this code. */ hsize = HSIZE; /* For dynamic table sizing. */ free_ent = 0; /* First unused entry. */ block_compress = BLOCK_MASK; clear_flg = 0; state = S_START; roffset = 0; size = 0; } --- NEW FILE: ftlzw.c --- /***************************************************************************/ /* */ /* ftlzw.c */ /* */ /* FreeType support for .Z compressed files. */ /* */ /* This optional component relies on NetBSD's zopen(). It should mainly */ /* be used to parse compressed PCF fonts, as found with many X11 server */ /* distributions. */ /* */ /* Copyright 2004, 2005 by */ /* Albert Chin-A-Young. */ /* */ /* Based on code in src/gzip/ftgzip.c, Copyright 2004 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. */ /* */ /***************************************************************************/ //#define FT_BITMAP_H #include <ft2build.h> #include FT_INTERNAL_MEMORY_H #include FT_INTERNAL_STREAM_H #include FT_INTERNAL_DEBUG_H #include <string.h> #include <stdio.h> #include FT_MODULE_ERRORS_H #undef __FTERRORS_H__ #define FT_ERR_PREFIX LZW_Err_ #define FT_ERR_BASE FT_Mod_Err_LZW #include FT_ERRORS_H #ifdef FT_CONFIG_OPTION_USE_LZW #include "zopen.h" /***************************************************************************/ /***************************************************************************/ /***** *****/ /***** M E M O R Y M A N A G E M E N T *****/ /***** *****/ /***************************************************************************/ /***************************************************************************/ /***************************************************************************/ /***************************************************************************/ /***** *****/ /***** F I L E D E S C R I P T O R *****/ /***** *****/ /***************************************************************************/ /***************************************************************************/ #define FT_LZW_BUFFER_SIZE 4096 typedef struct FT_LZWFileRec_ { FT_Stream source; /* parent/source stream */ FT_Stream stream; /* embedding stream */ FT_Memory memory; /* memory allocator */ s_zstate_t zstream; /* lzw input stream */ FT_ULong start; /* starting position, after .Z header */ FT_Byte input[FT_LZW_BUFFER_SIZE]; /* input buffer */ FT_Byte buffer[FT_LZW_BUFFER_SIZE]; /* output buffer */ FT_ULong pos; /* position in output */ FT_Byte* cursor; FT_Byte* limit; } FT_LZWFileRec, *FT_LZWFile; /* check and skip .Z header */ static FT_Error ft_lzw_check_header( FT_Stream stream ) { FT_Error error; FT_Byte head[2]; if ( FT_STREAM_SEEK( 0 ) || FT_STREAM_READ( head, 2 ) ) goto Exit; /* head[0] && head[1] are the magic numbers */ if ( head[0] != 0x1f || head[1] != 0x9d ) error = LZW_Err_Invalid_File_Format; Exit: return error; } static FT_Error ft_lzw_file_init( FT_LZWFile zip, FT_Stream stream, FT_Stream source ) { s_zstate_t* zstream = &zip->zstream; FT_Error error = LZW_Err_Ok; zip->stream = stream; zip->source = source; zip->memory = stream->memory; zip->limit = zip->buffer + FT_LZW_BUFFER_SIZE; zip->cursor = zip->limit; zip->pos = 0; /* check and skip .Z header */ { stream = source; error = ft_lzw_check_header( source ); if ( error ) goto Exit; zip->start = FT_STREAM_POS(); } /* initialize internal lzw variable */ zinit( zstream ); zstream->avail_in = 0; zstream->next_in = zip->buffer; zstream->zs_in_count = source->size - 2; if ( zstream->next_in == NULL ) error = LZW_Err_Invalid_File_Format; Exit: return error; } static void ft_lzw_file_done( FT_LZWFile zip ) { s_zstate_t* zstream = &zip->zstream; /* clear the rest */ zstream->next_in = NULL; zstream->next_out = NULL; zstream->avail_in = 0; zstream->avail_out = 0; zstream->total_in = 0; zstream->total_out = 0; zip->memory = NULL; zip->source = NULL; zip->stream = NULL; } static FT_Error ft_lzw_file_reset( FT_LZWFile zip ) { FT_Stream stream = zip->source; FT_Error error; if ( !FT_STREAM_SEEK( zip->start ) ) { s_zstate_t* zstream = &zip->zstream; zinit( zstream ); zstream->avail_in = 0; zstream->next_in = zip->input; zstream->total_in = 0; zstream->avail_out = 0; zstream->next_out = zip->buffer; zstream->total_out = 0; zstream->zs_in_count = zip->source->size - 2; zip->limit = zip->buffer + FT_LZW_BUFFER_SIZE; zip->cursor = zip->limit; zip->pos = 0; } return error; } static FT_Error ft_lzw_file_fill_input( FT_LZWFile zip ) { s_zstate_t* zstream = &zip->zstream; FT_Stream stream = zip->source; FT_ULong size; if ( stream->read ) { size = stream->read( stream, stream->pos, zip->input, FT_LZW_BUFFER_SIZE ); if ( size == 0 ) return LZW_Err_Invalid_Stream_Operation; } else { size = stream->size - stream->pos; if ( size > FT_LZW_BUFFER_SIZE ) size = FT_LZW_BUFFER_SIZE; if ( size == 0 ) return LZW_Err_Invalid_Stream_Operation; FT_MEM_COPY( zip->input, stream->base + stream->pos, size ); } stream->pos += size; zstream->next_in = zip->input; zstream->avail_in = size; return LZW_Err_Ok; } static FT_Error ft_lzw_file_fill_output( FT_LZWFile zip ) { s_zstate_t* zstream = &zip->zstream; FT_Error error = 0; zip->cursor = zip->buffer; zstream->next_out = zip->cursor; zstream->avail_out = FT_LZW_BUFFER_SIZE; while ( zstream->avail_out > 0 ) { int num_read = 0; if ( zstream->avail_in == 0 ) { error = ft_lzw_file_fill_input( zip ); if ( error ) break; } num_read = zread( zstream ); if ( num_read == -1 && zstream->zs_in_count == 0 ) { zip->limit = zstream->next_out; if ( zip->limit == zip->cursor ) error = LZW_Err_Invalid_Stream_Operation; break; } else if ( num_read == -1 ) break; else zstream->avail_out -= num_read; } return error; } /* fill output buffer; `count' must be <= FT_LZW_BUFFER_SIZE */ static FT_Error ft_lzw_file_skip_output( FT_LZWFile zip, FT_ULong count ) { FT_Error error = LZW_Err_Ok; FT_ULong delta; for (;;) { delta = (FT_ULong)( zip->limit - zip->cursor ); if ( delta >= count ) delta = count; zip->cursor += delta; zip->pos += delta; count -= delta; if ( count == 0 ) break; error = ft_lzw_file_fill_output( zip ); if ( error ) break; } return error; } static FT_ULong ft_lzw_file_io( FT_LZWFile zip, FT_ULong pos, FT_Byte* buffer, FT_ULong count ) { FT_ULong result = 0; FT_Error error; /* Teset inflate stream if we're seeking backwards. */ /* Yes, that is not too efficient, but it saves memory :-) */ if ( pos < zip->pos ) { error = ft_lzw_file_reset( zip ); if ( error ) goto Exit; } /* skip unwanted bytes */ if ( pos > zip->pos ) { error = ft_lzw_file_skip_output( zip, (FT_ULong)( pos - zip->pos ) ); if ( error ) goto Exit; } if ( count == 0 ) goto Exit; /* now read the data */ for (;;) { FT_ULong delta; delta = (FT_ULong)( zip->limit - zip->cursor ); if ( delta >= count ) delta = count; FT_MEM_COPY( buffer, zip->cursor, delta ); buffer += delta; result += delta; zip->cursor += delta; zip->pos += delta; count -= delta; if ( count == 0 ) break; error = ft_lzw_file_fill_output( zip ); if ( error ) break; } Exit: return result; } /***************************************************************************/ /***************************************************************************/ /***** *****/ /***** L Z W E M B E D D I N G S T R E A M *****/ /***** *****/ /***************************************************************************/ /***************************************************************************/ static void ft_lzw_stream_close( FT_Stream stream ) { FT_LZWFile zip = (FT_LZWFile)stream->descriptor.pointer; FT_Memory memory = stream->memory; if ( zip ) { /* finalize lzw file descriptor */ ft_lzw_file_done( zip ); FT_FREE( zip ); stream->descriptor.pointer = NULL; } } static FT_ULong ft_lzw_stream_io( FT_Stream stream, FT_ULong pos, FT_Byte* buffer, FT_ULong count ) { FT_LZWFile zip = (FT_LZWFile)stream->descriptor.pointer; return ft_lzw_file_io( zip, pos, buffer, count ); } FT_EXPORT_DEF( FT_Error ) FT_Stream_OpenLZW( FT_Stream stream, FT_Stream source ) { FT_Error error; FT_Memory memory = source->memory; FT_LZWFile zip; /* * Check the header right now; this prevents allocation a huge * LZWFile object (400 KByte of heap memory) if not necessary. * * Did I mention that you should never use .Z compressed font * file? */ error = ft_lzw_check_header( source ); if ( error ) goto Exit; FT_ZERO( stream ); stream->memory = memory; if ( !FT_NEW( zip ) ) { error = ft_lzw_file_init( zip, stream, source ); if ( error ) { FT_FREE( zip ); goto Exit; } stream->descriptor.pointer = zip; } stream->size = 0x7FFFFFFFL; /* don't know the real size! */ stream->pos = 0; stream->base = 0; stream->read = ft_lzw_stream_io; stream->close = ft_lzw_stream_close; Exit: return error; } #include "zopen.c" #else /* !FT_CONFIG_OPTION_USE_LZW */ FT_EXPORT_DEF( FT_Error ) FT_Stream_OpenLZW( FT_Stream stream, FT_Stream source ) { FT_UNUSED( stream ); FT_UNUSED( source ); return LZW_Err_Unimplemented_Feature; } #endif /* !FT_CONFIG_OPTION_USE_LZW */ /* END */ |
|
From: Ehud S. <esh...@us...> - 2006-04-21 16:22:37
|
Update of /cvsroot/roadmap/roadmap_editor/src/freetype/src/pcf In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv22848/src/pcf Added Files: pcf.c pcfdrivr.c pcfread.c pcfutil.c Log Message: Import freetype sources. --- NEW FILE: pcfdrivr.c --- /* pcfdrivr.c FreeType font driver for pcf files Copyright (C) 2000, 2001, 2002, 2003, 2004 by Francesco Zappa Nardelli Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include <ft2build.h> #include FT_INTERNAL_DEBUG_H #include FT_INTERNAL_STREAM_H #include FT_INTERNAL_OBJECTS_H #include FT_GZIP_H #include FT_LZW_H #include FT_ERRORS_H #include FT_BDF_H #include "pcf.h" #include "pcfdrivr.h" #include "pcfread.h" #include "pcferror.h" #include "pcfutil.h" #undef FT_COMPONENT #define FT_COMPONENT trace_pcfread #include FT_SERVICE_BDF_H #include FT_SERVICE_XFREE86_NAME_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_pcfdriver typedef struct PCF_CMapRec_ { FT_CMapRec root; FT_UInt num_encodings; PCF_Encoding encodings; } PCF_CMapRec, *PCF_CMap; FT_CALLBACK_DEF( FT_Error ) pcf_cmap_init( FT_CMap pcfcmap, /* PCF_CMap */ FT_Pointer init_data ) { PCF_CMap cmap = (PCF_CMap)pcfcmap; PCF_Face face = (PCF_Face)FT_CMAP_FACE( pcfcmap ); FT_UNUSED( init_data ); cmap->num_encodings = (FT_UInt)face->nencodings; cmap->encodings = face->encodings; return PCF_Err_Ok; } FT_CALLBACK_DEF( void ) pcf_cmap_done( FT_CMap pcfcmap ) /* PCF_CMap */ { PCF_CMap cmap = (PCF_CMap)pcfcmap; cmap->encodings = NULL; cmap->num_encodings = 0; } FT_CALLBACK_DEF( FT_UInt ) pcf_cmap_char_index( FT_CMap pcfcmap, /* PCF_CMap */ FT_UInt32 charcode ) { PCF_CMap cmap = (PCF_CMap)pcfcmap; PCF_Encoding encodings = cmap->encodings; FT_UInt min, max, mid; FT_UInt result = 0; min = 0; max = cmap->num_encodings; while ( min < max ) { FT_UInt32 code; mid = ( min + max ) >> 1; code = encodings[mid].enc; if ( charcode == code ) { result = encodings[mid].glyph + 1; break; } if ( charcode < code ) max = mid; else min = mid + 1; } return result; } FT_CALLBACK_DEF( FT_UInt ) pcf_cmap_char_next( FT_CMap pcfcmap, /* PCF_CMap */ FT_UInt32 *acharcode ) { PCF_CMap cmap = (PCF_CMap)pcfcmap; PCF_Encoding encodings = cmap->encodings; FT_UInt min, max, mid; FT_UInt32 charcode = *acharcode + 1; FT_UInt result = 0; min = 0; max = cmap->num_encodings; while ( min < max ) { FT_UInt32 code; mid = ( min + max ) >> 1; code = encodings[mid].enc; if ( charcode == code ) { result = encodings[mid].glyph + 1; goto Exit; } if ( charcode < code ) max = mid; else min = mid + 1; } charcode = 0; if ( min < cmap->num_encodings ) { charcode = encodings[min].enc; result = encodings[min].glyph + 1; } Exit: *acharcode = charcode; return result; } FT_CALLBACK_TABLE_DEF const FT_CMap_ClassRec pcf_cmap_class = { sizeof ( PCF_CMapRec ), pcf_cmap_init, pcf_cmap_done, pcf_cmap_char_index, pcf_cmap_char_next }; FT_CALLBACK_DEF( void ) PCF_Face_Done( FT_Face pcfface ) /* PCF_Face */ { PCF_Face face = (PCF_Face)pcfface; FT_Memory memory = FT_FACE_MEMORY( face ); FT_FREE( face->encodings ); FT_FREE( face->metrics ); /* free properties */ { PCF_Property prop = face->properties; FT_Int i; for ( i = 0; i < face->nprops; i++ ) { prop = &face->properties[i]; FT_FREE( prop->name ); if ( prop->isString ) FT_FREE( prop->value ); } FT_FREE( face->properties ); } FT_FREE( face->toc.tables ); FT_FREE( pcfface->family_name ); FT_FREE( pcfface->style_name ); FT_FREE( pcfface->available_sizes ); FT_FREE( face->charset_encoding ); FT_FREE( face->charset_registry ); FT_TRACE4(( "PCF_Face_Done: done face\n" )); /* close gzip/LZW stream if any */ if ( pcfface->stream == &face->gzip_stream ) { FT_Stream_Close( &face->gzip_stream ); pcfface->stream = face->gzip_source; } } FT_CALLBACK_DEF( FT_Error ) PCF_Face_Init( FT_Stream stream, FT_Face pcfface, /* PCF_Face */ FT_Int face_index, FT_Int num_params, FT_Parameter* params ) { PCF_Face face = (PCF_Face)pcfface; FT_Error error = PCF_Err_Ok; FT_UNUSED( num_params ); FT_UNUSED( params ); FT_UNUSED( face_index ); error = pcf_load_font( stream, face ); if ( error ) { FT_Error error2; /* this didn't work, try gzip support! */ error2 = FT_Stream_OpenGzip( &face->gzip_stream, stream ); if ( FT_ERROR_BASE( error2 ) == FT_Err_Unimplemented_Feature ) goto Fail; error = error2; if ( error ) { FT_Error error3; /* this didn't work, try LZW support! */ error3 = FT_Stream_OpenLZW( &face->gzip_stream, stream ); if ( FT_ERROR_BASE( error3 ) == FT_Err_Unimplemented_Feature ) goto Fail; error = error3; if ( error ) goto Fail; face->gzip_source = stream; pcfface->stream = &face->gzip_stream; stream = pcfface->stream; error = pcf_load_font( stream, face ); if ( error ) goto Fail; } else { face->gzip_source = stream; pcfface->stream = &face->gzip_stream; stream = pcfface->stream; error = pcf_load_font( stream, face ); if ( error ) goto Fail; } } /* set up charmap */ { FT_String *charset_registry = face->charset_registry; FT_String *charset_encoding = face->charset_encoding; FT_Bool unicode_charmap = 0; if ( charset_registry && charset_encoding ) { char* s = charset_registry; /* Uh, oh, compare first letters manually to avoid dependency on locales. */ if ( ( s[0] == 'i' || s[0] == 'I' ) && ( s[1] == 's' || s[1] == 'S' ) && ( s[2] == 'o' || s[2] == 'O' ) ) { s += 3; if ( !ft_strcmp( s, "10646" ) || ( !ft_strcmp( s, "8859" ) && !ft_strcmp( face->charset_encoding, "1" ) ) ) unicode_charmap = 1; } } { FT_CharMapRec charmap; charmap.face = FT_FACE( face ); charmap.encoding = FT_ENCODING_NONE; charmap.platform_id = 0; charmap.encoding_id = 0; if ( unicode_charmap ) { charmap.encoding = FT_ENCODING_UNICODE; charmap.platform_id = 3; charmap.encoding_id = 1; } error = FT_CMap_New( &pcf_cmap_class, NULL, &charmap, NULL ); #if 0 /* Select default charmap */ if ( pcfface->num_charmaps ) pcfface->charmap = pcfface->charmaps[0]; #endif } } Exit: return error; Fail: FT_TRACE2(( "[not a valid PCF file]\n" )); error = PCF_Err_Unknown_File_Format; /* error */ goto Exit; } FT_CALLBACK_DEF( FT_Error ) PCF_Set_Pixel_Size( FT_Size size, FT_UInt pixel_width, FT_UInt pixel_height ) { PCF_Face face = (PCF_Face)FT_SIZE_FACE( size ); FT_UNUSED( pixel_width ); if ( pixel_height == (FT_UInt)face->root.available_sizes->height ) { size->metrics.ascender = face->accel.fontAscent << 6; size->metrics.descender = face->accel.fontDescent * (-64); #if 0 size->metrics.height = face->accel.maxbounds.ascent << 6; #endif size->metrics.height = size->metrics.ascender - size->metrics.descender; size->metrics.max_advance = face->accel.maxbounds.characterWidth << 6; return PCF_Err_Ok; } else { FT_TRACE4(( "pixel size WRONG\n" )); return PCF_Err_Invalid_Pixel_Size; } } FT_CALLBACK_DEF( FT_Error ) PCF_Set_Point_Size( FT_Size size, FT_F26Dot6 char_width, FT_F26Dot6 char_height, FT_UInt horz_resolution, FT_UInt vert_resolution ) { PCF_Face face = (PCF_Face)FT_SIZE_FACE( size ); FT_UNUSED( char_width ); FT_UNUSED( char_height ); FT_UNUSED( horz_resolution ); FT_UNUSED( vert_resolution ); FT_TRACE4(( "rec %d - pres %d\n", size->metrics.y_ppem, face->root.available_sizes->y_ppem >> 6 )); if ( size->metrics.y_ppem == face->root.available_sizes->y_ppem >> 6 ) { size->metrics.ascender = face->accel.fontAscent << 6; size->metrics.descender = face->accel.fontDescent * (-64); #if 0 size->metrics.height = face->accel.maxbounds.ascent << 6; #endif size->metrics.height = size->metrics.ascender - size->metrics.descender; size->metrics.max_advance = face->accel.maxbounds.characterWidth << 6; return PCF_Err_Ok; } else { FT_TRACE4(( "size WRONG\n" )); return PCF_Err_Invalid_Pixel_Size; } } FT_CALLBACK_DEF( FT_Error ) PCF_Glyph_Load( FT_GlyphSlot slot, FT_Size size, FT_UInt glyph_index, FT_Int32 load_flags ) { PCF_Face face = (PCF_Face)FT_SIZE_FACE( size ); FT_Stream stream = face->root.stream; FT_Error error = PCF_Err_Ok; FT_Bitmap* bitmap = &slot->bitmap; PCF_Metric metric; int bytes; FT_UNUSED( load_flags ); FT_TRACE4(( "load_glyph %d ---", glyph_index )); if ( !face ) { error = PCF_Err_Invalid_Argument; goto Exit; } if ( glyph_index > 0 ) glyph_index--; metric = face->metrics + glyph_index; bitmap->rows = metric->ascent + metric->descent; bitmap->width = metric->rightSideBearing - metric->leftSideBearing; bitmap->num_grays = 1; bitmap->pixel_mode = FT_PIXEL_MODE_MONO; FT_TRACE6(( "BIT_ORDER %d ; BYTE_ORDER %d ; GLYPH_PAD %d\n", PCF_BIT_ORDER( face->bitmapsFormat ), PCF_BYTE_ORDER( face->bitmapsFormat ), PCF_GLYPH_PAD( face->bitmapsFormat ) )); switch ( PCF_GLYPH_PAD( face->bitmapsFormat ) ) { case 1: bitmap->pitch = ( bitmap->width + 7 ) >> 3; break; case 2: bitmap->pitch = ( ( bitmap->width + 15 ) >> 4 ) << 1; break; case 4: bitmap->pitch = ( ( bitmap->width + 31 ) >> 5 ) << 2; break; case 8: bitmap->pitch = ( ( bitmap->width + 63 ) >> 6 ) << 3; break; default: return PCF_Err_Invalid_File_Format; } /* XXX: to do: are there cases that need repadding the bitmap? */ bytes = bitmap->pitch * bitmap->rows; error = ft_glyphslot_alloc_bitmap( slot, bytes ); if ( error ) goto Exit; if ( FT_STREAM_SEEK( metric->bits ) || FT_STREAM_READ( bitmap->buffer, bytes ) ) goto Exit; if ( PCF_BIT_ORDER( face->bitmapsFormat ) != MSBFirst ) BitOrderInvert( bitmap->buffer, bytes ); if ( ( PCF_BYTE_ORDER( face->bitmapsFormat ) != PCF_BIT_ORDER( face->bitmapsFormat ) ) ) { switch ( PCF_SCAN_UNIT( face->bitmapsFormat ) ) { case 1: break; case 2: TwoByteSwap( bitmap->buffer, bytes ); break; case 4: FourByteSwap( bitmap->buffer, bytes ); break; } } slot->bitmap_left = metric->leftSideBearing; slot->bitmap_top = metric->ascent; slot->metrics.horiAdvance = metric->characterWidth << 6; slot->metrics.horiBearingX = metric->leftSideBearing << 6; slot->metrics.horiBearingY = metric->ascent << 6; slot->metrics.width = ( metric->rightSideBearing - metric->leftSideBearing ) << 6; slot->metrics.height = bitmap->rows << 6; slot->linearHoriAdvance = (FT_Fixed)bitmap->width << 16; slot->format = FT_GLYPH_FORMAT_BITMAP; FT_TRACE4(( " --- ok\n" )); Exit: return error; } /* * * BDF SERVICE * */ static FT_Error pcf_get_bdf_property( PCF_Face face, const char* prop_name, BDF_PropertyRec *aproperty ) { PCF_Property prop; prop = pcf_find_property( face, prop_name ); if ( prop != NULL ) { if ( prop->isString ) { aproperty->type = BDF_PROPERTY_TYPE_ATOM; aproperty->u.atom = prop->value.atom; } else { /* Apparently, the PCF driver loads all properties as signed integers! * This really doesn't seem to be a problem, because this is * sufficient for any meaningful values. */ aproperty->type = BDF_PROPERTY_TYPE_INTEGER; aproperty->u.integer = prop->value.integer; } return 0; } return PCF_Err_Invalid_Argument; } static FT_Error pcf_get_charset_id( PCF_Face face, const char* *acharset_encoding, const char* *acharset_registry ) { *acharset_encoding = face->charset_encoding; *acharset_registry = face->charset_registry; return 0; } static const FT_Service_BDFRec pcf_service_bdf = { (FT_BDF_GetCharsetIdFunc)pcf_get_charset_id, (FT_BDF_GetPropertyFunc) pcf_get_bdf_property }; /* * * SERVICE LIST * */ static const FT_ServiceDescRec pcf_services[] = { { FT_SERVICE_ID_BDF, &pcf_service_bdf }, { FT_SERVICE_ID_XF86_NAME, FT_XF86_FORMAT_PCF }, { NULL, NULL } }; FT_CALLBACK_DEF( FT_Module_Interface ) pcf_driver_requester( FT_Module module, const char* name ) { FT_UNUSED( module ); return ft_service_list_lookup( pcf_services, name ); } FT_CALLBACK_TABLE_DEF const FT_Driver_ClassRec pcf_driver_class = { { FT_MODULE_FONT_DRIVER | FT_MODULE_DRIVER_NO_OUTLINES, sizeof ( FT_DriverRec ), "pcf", 0x10000L, 0x20000L, 0, 0, 0, pcf_driver_requester }, sizeof ( PCF_FaceRec ), sizeof ( FT_SizeRec ), sizeof ( FT_GlyphSlotRec ), PCF_Face_Init, PCF_Face_Done, 0, /* FT_Size_InitFunc */ 0, /* FT_Size_DoneFunc */ 0, /* FT_Slot_InitFunc */ 0, /* FT_Slot_DoneFunc */ PCF_Set_Point_Size, PCF_Set_Pixel_Size, PCF_Glyph_Load, 0, /* FT_Face_GetKerningFunc */ 0, /* FT_Face_AttachFunc */ 0 /* FT_Face_GetAdvancesFunc */ }; /* END */ --- NEW FILE: pcfread.c --- /* pcfread.c FreeType font driver for pcf fonts Copyright 2000, 2001, 2002, 2003, 2004, 2005 by Francesco Zappa Nardelli Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, [...1143 lines suppressed...] ft_strcpy( face->charset_registry, charset_registry->value.atom ); ft_strcpy( face->charset_encoding, charset_encoding->value.atom ); } } } Exit: if ( error ) { /* this is done to respect the behaviour of the original */ /* PCF font driver. */ error = PCF_Err_Invalid_File_Format; } return error; } /* END */ --- NEW FILE: pcf.c --- /* pcf.c FreeType font driver for pcf fonts Copyright 2000-2001, 2003 by Francesco Zappa Nardelli Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #define FT_MAKE_OPTION_SINGLE_OBJECT #include <ft2build.h> #include "pcfutil.c" #include "pcfread.c" #include "pcfdrivr.c" /* END */ --- NEW FILE: pcfutil.c --- /* Copyright 1990, 1994, 1998 The Open Group All Rights Reserved. The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. Except as contained in this notice, the name of The Open Group shall not be used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization from The Open Group. */ /* $XFree86: xc/lib/font/util/utilbitmap.c,v 1.3 1999/08/22 08:58:58 dawes Exp $ */ /* * Author: Keith Packard, MIT X Consortium */ /* Modified for use with FreeType */ #include <ft2build.h> #include "pcfutil.h" /* * Invert bit order within each BYTE of an array. */ FT_LOCAL_DEF( void ) BitOrderInvert( unsigned char* buf, int nbytes ) { for ( ; --nbytes >= 0; buf++ ) { unsigned int val = *buf; val = ( ( val >> 1 ) & 0x55 ) | ( ( val << 1 ) & 0xAA ); val = ( ( val >> 2 ) & 0x33 ) | ( ( val << 2 ) & 0xCC ); val = ( ( val >> 4 ) & 0x0F ) | ( ( val << 4 ) & 0xF0 ); *buf = (unsigned char)val; } } /* * Invert byte order within each 16-bits of an array. */ FT_LOCAL_DEF( void ) TwoByteSwap( unsigned char* buf, int nbytes ) { unsigned char c; for ( ; nbytes >= 2; nbytes -= 2, buf += 2 ) { c = buf[0]; buf[0] = buf[1]; buf[1] = c; } } /* * Invert byte order within each 32-bits of an array. */ FT_LOCAL_DEF( void ) FourByteSwap( unsigned char* buf, int nbytes ) { unsigned char c; for ( ; nbytes >= 4; nbytes -= 4, buf += 4 ) { c = buf[0]; buf[0] = buf[3]; buf[3] = c; c = buf[1]; buf[1] = buf[2]; buf[2] = c; } } /* END */ |
|
From: Ehud S. <esh...@us...> - 2006-04-21 16:22:37
|
Update of /cvsroot/roadmap/roadmap_editor/src/freetype/src/truetype In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv22848/src/truetype Added Files: truetype.c ttdriver.c ttgload.c ttgxvar.c ttinterp.c ttobjs.c ttpload.c Log Message: Import freetype sources. --- NEW FILE: ttinterp.c --- /***************************************************************************/ /* */ /* ttinterp.c */ /* */ /* TrueType bytecode interpreter (body). */ /* */ /* Copyright 1996-2001, 2002, 2003, 2004 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> [...7699 lines suppressed...] return TT_Err_Ok; LErrorCodeOverflow_: CUR.error = TT_Err_Code_Overflow; LErrorLabel_: #ifdef TT_CONFIG_OPTION_STATIC_RASTER *exc = cur; #endif return CUR.error; } #endif /* TT_CONFIG_OPTION_BYTECODE_INTERPRETER */ /* END */ --- NEW FILE: truetype.c --- /***************************************************************************/ /* */ /* truetype.c */ /* */ /* FreeType TrueType driver component (body only). */ /* */ /* Copyright 1996-2001, 2004 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. */ /* */ /***************************************************************************/ #define FT_MAKE_OPTION_SINGLE_OBJECT #include <ft2build.h> #include "ttdriver.c" /* driver interface */ #include "ttpload.c" /* tables loader */ #include "ttgload.c" /* glyph loader */ #include "ttobjs.c" /* object manager */ #ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER #include "ttinterp.c" #endif #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT #include "ttgxvar.c" /* gx distortable font */ #endif /* END */ --- NEW FILE: ttobjs.c --- /***************************************************************************/ /* */ /* ttobjs.c */ /* */ /* Objects manager (body). */ /* */ /* Copyright 1996-2001, 2002, 2003, 2004, 2005 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_CALC_H #include FT_INTERNAL_STREAM_H #include FT_TRUETYPE_IDS_H #include FT_TRUETYPE_TAGS_H #include FT_INTERNAL_SFNT_H #include "ttgload.h" #include "ttpload.h" #include "tterrors.h" #ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER #include "ttinterp.h" #endif #ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING #include FT_TRUETYPE_UNPATENTED_H #endif #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT #include "ttgxvar.h" #endif /*************************************************************************/ /* */ /* 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_ttobjs #ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER /*************************************************************************/ /* */ /* GLYPH ZONE FUNCTIONS */ /* */ /*************************************************************************/ /*************************************************************************/ /* */ /* <Function> */ /* tt_glyphzone_done */ /* */ /* <Description> */ /* Deallocates a glyph zone. */ /* */ /* <Input> */ /* zone :: A pointer to the target glyph zone. */ /* */ FT_LOCAL_DEF( void ) tt_glyphzone_done( TT_GlyphZone zone ) { FT_Memory memory = zone->memory; if ( memory ) { FT_FREE( zone->contours ); FT_FREE( zone->tags ); FT_FREE( zone->cur ); FT_FREE( zone->org ); zone->max_points = zone->n_points = 0; zone->max_contours = zone->n_contours = 0; zone->memory = NULL; } } /*************************************************************************/ /* */ /* <Function> */ /* tt_glyphzone_new */ /* */ /* <Description> */ /* Allocates a new glyph zone. */ /* */ /* <Input> */ /* memory :: A handle to the current memory object. */ /* */ /* maxPoints :: The capacity of glyph zone in points. */ /* */ /* maxContours :: The capacity of glyph zone in contours. */ /* */ /* <Output> */ /* zone :: A pointer to the target glyph zone record. */ /* */ /* <Return> */ /* FreeType error code. 0 means success. */ /* */ FT_LOCAL_DEF( FT_Error ) tt_glyphzone_new( FT_Memory memory, FT_UShort maxPoints, FT_Short maxContours, TT_GlyphZone zone ) { FT_Error error; if ( maxPoints > 0 ) maxPoints += 2; FT_MEM_ZERO( zone, sizeof ( *zone ) ); zone->memory = memory; if ( FT_NEW_ARRAY( zone->org, maxPoints * 2 ) || FT_NEW_ARRAY( zone->cur, maxPoints * 2 ) || FT_NEW_ARRAY( zone->tags, maxPoints ) || FT_NEW_ARRAY( zone->contours, maxContours ) ) { tt_glyphzone_done( zone ); } return error; } #endif /* TT_CONFIG_OPTION_BYTECODE_INTERPRETER */ /*************************************************************************/ /* */ /* <Function> */ /* tt_face_init */ /* */ /* <Description> */ /* Initializes a given TrueType face object. */ /* */ /* <Input> */ /* stream :: The source font stream. */ /* */ /* face_index :: The index of the font face in the resource. */ /* */ /* num_params :: Number of additional generic parameters. Ignored. */ /* */ /* params :: Additional generic parameters. Ignored. */ /* */ /* <InOut> */ /* face :: The newly built face object. */ /* */ /* <Return> */ /* FreeType error code. 0 means success. */ /* */ FT_LOCAL_DEF( FT_Error ) tt_face_init( FT_Stream stream, FT_Face ttface, /* TT_Face */ FT_Int face_index, FT_Int num_params, FT_Parameter* params ) { FT_Error error; FT_Library library; SFNT_Service sfnt; TT_Face face = (TT_Face)ttface; library = face->root.driver->root.library; sfnt = (SFNT_Service)FT_Get_Module_Interface( library, "sfnt" ); if ( !sfnt ) goto Bad_Format; /* create input stream from resource */ if ( FT_STREAM_SEEK( 0 ) ) goto Exit; /* check that we have a valid TrueType file */ error = sfnt->init_face( stream, face, face_index, num_params, params ); if ( error ) goto Exit; /* We must also be able to accept Mac/GX fonts, as well as OT ones. */ /* The 0x00020000 tag is completely undocumented; some fonts from */ /* Arphic made for Chinese Windows 3.1 have this. */ if ( face->format_tag != 0x00010000L && /* MS fonts */ face->format_tag != 0x00020000L && /* CJK fonts for Win 3.1 */ face->format_tag != TTAG_true ) /* Mac fonts */ { FT_TRACE2(( "[not a valid TTF font]\n" )); goto Bad_Format; } /* If we are performing a simple font format check, exit immediately */ if ( face_index < 0 ) return TT_Err_Ok; /* Load font directory */ error = sfnt->load_face( stream, face, face_index, num_params, params ); if ( error ) goto Exit; if ( face->root.face_flags & FT_FACE_FLAG_SCALABLE ) { #ifdef FT_CONFIG_OPTION_INCREMENTAL if ( !face->root.internal->incremental_interface ) error = tt_face_load_loca( face, stream ); if ( !error ) { error = tt_face_load_cvt( face, stream ); if ( !error ) error = tt_face_load_fpgm( face, stream ); } #else if ( !error ) error = tt_face_load_loca( face, stream ) || tt_face_load_cvt( face, stream ) || tt_face_load_fpgm( face, stream ); #endif } #ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING /* Determine whether unpatented hinting is to be used for this face. */ face->unpatented_hinting = FT_BOOL ( library->debug_hooks[ FT_DEBUG_HOOK_UNPATENTED_HINTING ] != NULL ); { int i; for ( i = 0; i < num_params && !face->unpatented_hinting; i++ ) if ( params[i].tag == FT_PARAM_TAG_UNPATENTED_HINTING ) face->unpatented_hinting = TRUE; } #endif /* TT_CONFIG_OPTION_UNPATENTED_HINTING */ /* initialize standard glyph loading routines */ TT_Init_Glyph_Loading( face ); Exit: return error; Bad_Format: error = TT_Err_Unknown_File_Format; goto Exit; } /*************************************************************************/ /* */ /* <Function> */ /* tt_face_done */ /* */ /* <Description> */ /* Finalizes a given face object. */ /* */ /* <Input> */ /* face :: A pointer to the face object to destroy. */ /* */ FT_LOCAL_DEF( void ) tt_face_done( FT_Face ttface ) /* TT_Face */ { TT_Face face = (TT_Face)ttface; FT_Memory memory = face->root.memory; FT_Stream stream = face->root.stream; SFNT_Service sfnt = (SFNT_Service)face->sfnt; /* for `extended TrueType formats' (i.e. compressed versions) */ if ( face->extra.finalizer ) face->extra.finalizer( face->extra.data ); if ( sfnt ) sfnt->done_face( face ); /* freeing the locations table */ tt_face_done_loca( face ); /* freeing the CVT */ FT_FREE( face->cvt ); face->cvt_size = 0; /* freeing the programs */ FT_FRAME_RELEASE( face->font_program ); FT_FRAME_RELEASE( face->cvt_program ); face->font_program_size = 0; face->cvt_program_size = 0; #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT tt_done_blend( memory, face->blend ); face->blend = NULL; #endif } /*************************************************************************/ /* */ /* SIZE FUNCTIONS */ /* */ /*************************************************************************/ /*************************************************************************/ /* */ /* <Function> */ /* tt_size_init */ /* */ /* <Description> */ /* Initializes a new TrueType size object. */ /* */ /* <InOut> */ /* size :: A handle to the size object. */ /* */ /* <Return> */ /* FreeType error code. 0 means success. */ /* */ FT_LOCAL_DEF( FT_Error ) tt_size_init( FT_Size ttsize ) /* TT_Size */ { TT_Size size = (TT_Size)ttsize; FT_Error error = TT_Err_Ok; #ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER TT_Face face = (TT_Face)size->root.face; FT_Memory memory = face->root.memory; FT_Int i; TT_ExecContext exec; FT_UShort n_twilight; TT_MaxProfile* maxp = &face->max_profile; size->ttmetrics.valid = FALSE; size->max_function_defs = maxp->maxFunctionDefs; size->max_instruction_defs = maxp->maxInstructionDefs; size->num_function_defs = 0; size->num_instruction_defs = 0; size->max_func = 0; size->max_ins = 0; size->cvt_size = face->cvt_size; size->storage_size = maxp->maxStorage; /* Set default metrics */ { FT_Size_Metrics* metrics = &size->root.metrics; TT_Size_Metrics* metrics2 = &size->ttmetrics; metrics->x_ppem = 0; metrics->y_ppem = 0; metrics2->rotated = FALSE; metrics2->stretched = FALSE; /* set default compensation (all 0) */ for ( i = 0; i < 4; i++ ) metrics2->compensations[i] = 0; } /* allocate function defs, instruction defs, cvt, and storage area */ if ( FT_NEW_ARRAY( size->function_defs, size->max_function_defs ) || FT_NEW_ARRAY( size->instruction_defs, size->max_instruction_defs ) || FT_NEW_ARRAY( size->cvt, size->cvt_size ) || FT_NEW_ARRAY( size->storage, size->storage_size ) ) goto Fail_Memory; /* reserve twilight zone */ n_twilight = maxp->maxTwilightPoints; error = tt_glyphzone_new( memory, n_twilight, 0, &size->twilight ); if ( error ) goto Fail_Memory; size->twilight.n_points = n_twilight; /* set `face->interpreter' according to the debug hook present */ { FT_Library library = face->root.driver->root.library; face->interpreter = (TT_Interpreter) library->debug_hooks[FT_DEBUG_HOOK_TRUETYPE]; if ( !face->interpreter ) face->interpreter = (TT_Interpreter)TT_RunIns; } /* Fine, now execute the font program! */ exec = size->context; /* size objects used during debugging have their own context */ if ( !size->debug ) exec = TT_New_Context( face ); if ( !exec ) { error = TT_Err_Could_Not_Find_Context; goto Fail_Memory; } size->GS = tt_default_graphics_state; TT_Load_Context( exec, face, size ); exec->callTop = 0; exec->top = 0; exec->period = 64; exec->phase = 0; exec->threshold = 0; { FT_Size_Metrics* metrics = &exec->metrics; TT_Size_Metrics* tt_metrics = &exec->tt_metrics; metrics->x_ppem = 0; metrics->y_ppem = 0; metrics->x_scale = 0; metrics->y_scale = 0; tt_metrics->ppem = 0; tt_metrics->scale = 0; tt_metrics->ratio = 0x10000L; } exec->instruction_trap = FALSE; exec->cvtSize = size->cvt_size; exec->cvt = size->cvt; exec->F_dot_P = 0x10000L; /* allow font program execution */ TT_Set_CodeRange( exec, tt_coderange_font, face->font_program, face->font_program_size ); /* disable CVT and glyph programs coderange */ TT_Clear_CodeRange( exec, tt_coderange_cvt ); TT_Clear_CodeRange( exec, tt_coderange_glyph ); if ( face->font_program_size > 0 ) { error = TT_Goto_CodeRange( exec, tt_coderange_font, 0 ); if ( !error ) error = face->interpreter( exec ); if ( error ) goto Fail_Exec; } else error = TT_Err_Ok; TT_Save_Context( exec, size ); if ( !size->debug ) TT_Done_Context( exec ); #endif /* TT_CONFIG_OPTION_BYTECODE_INTERPRETER */ size->ttmetrics.valid = FALSE; return error; #ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER Fail_Exec: if ( !size->debug ) TT_Done_Context( exec ); Fail_Memory: tt_size_done( ttsize ); return error; #endif /* TT_CONFIG_OPTION_BYTECODE_INTERPRETER */ } /*************************************************************************/ /* */ /* <Function> */ /* tt_size_done */ /* */ /* <Description> */ /* The TrueType size object finalizer. */ /* */ /* <Input> */ /* size :: A handle to the target size object. */ /* */ FT_LOCAL_DEF( void ) tt_size_done( FT_Size ttsize ) /* TT_Size */ { TT_Size size = (TT_Size)ttsize; #ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER FT_Memory memory = size->root.face->memory; if ( size->debug ) { /* the debug context must be deleted by the debugger itself */ size->context = NULL; size->debug = FALSE; } FT_FREE( size->cvt ); size->cvt_size = 0; /* free storage area */ FT_FREE( size->storage ); size->storage_size = 0; /* twilight zone */ tt_glyphzone_done( &size->twilight ); FT_FREE( size->function_defs ); FT_FREE( size->instruction_defs ); size->num_function_defs = 0; size->max_function_defs = 0; size->num_instruction_defs = 0; size->max_instruction_defs = 0; size->max_func = 0; size->max_ins = 0; #endif size->ttmetrics.valid = FALSE; } /*************************************************************************/ /* */ /* <Function> */ /* Reset_Outline_Size */ /* */ /* <Description> */ /* Resets a TrueType outline size when resolutions and character */ /* dimensions have been changed. */ /* */ /* <Input> */ /* size :: A handle to the target size object. */ /* */ static FT_Error Reset_Outline_Size( TT_Size size ) { TT_Face face; FT_Error error = TT_Err_Ok; FT_Size_Metrics* metrics; if ( size->ttmetrics.valid ) return TT_Err_Ok; face = (TT_Face)size->root.face; metrics = &size->metrics; if ( metrics->x_ppem < 1 || metrics->y_ppem < 1 ) return TT_Err_Invalid_PPem; /* compute new transformation */ if ( metrics->x_ppem >= metrics->y_ppem ) { size->ttmetrics.scale = metrics->x_scale; size->ttmetrics.ppem = metrics->x_ppem; size->ttmetrics.x_ratio = 0x10000L; size->ttmetrics.y_ratio = FT_MulDiv( metrics->y_ppem, 0x10000L, metrics->x_ppem ); } else { size->ttmetrics.scale = metrics->y_scale; size->ttmetrics.ppem = metrics->y_ppem; size->ttmetrics.x_ratio = FT_MulDiv( metrics->x_ppem, 0x10000L, metrics->y_ppem ); size->ttmetrics.y_ratio = 0x10000L; } /* Compute root ascender, descender, text height, and max_advance */ metrics->ascender = FT_PIX_ROUND( FT_MulFix( face->root.ascender, metrics->y_scale ) ); metrics->descender = FT_PIX_ROUND( FT_MulFix( face->root.descender, metrics->y_scale ) ); metrics->height = FT_PIX_ROUND( FT_MulFix( face->root.height, metrics->y_scale ) ); metrics->max_advance = FT_PIX_ROUND( FT_MulFix( face->root.max_advance_width, metrics->x_scale ) ); #ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS /* set to `invalid' by default */ size->strike_index = 0xFFFFU; #endif #ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER { TT_ExecContext exec; FT_UInt i, j; /* Scale the cvt values to the new ppem. */ /* We use by default the y ppem to scale the CVT. */ for ( i = 0; i < size->cvt_size; i++ ) size->cvt[i] = FT_MulFix( face->cvt[i], size->ttmetrics.scale ); /* All twilight points are originally zero */ for ( j = 0; j < (FT_UInt)size->twilight.n_points; j++ ) { size->twilight.org[j].x = 0; size->twilight.org[j].y = 0; size->twilight.cur[j].x = 0; size->twilight.cur[j].y = 0; } /* clear storage area */ for ( i = 0; i < (FT_UInt)size->storage_size; i++ ) size->storage[i] = 0; size->GS = tt_default_graphics_state; /* get execution context and run prep program */ if ( size->debug ) exec = size->context; else exec = TT_New_Context( face ); /* debugging instances have their own context */ if ( !exec ) return TT_Err_Could_Not_Find_Context; TT_Load_Context( exec, face, size ); TT_Set_CodeRange( exec, tt_coderange_cvt, face->cvt_program, face->cvt_program_size ); TT_Clear_CodeRange( exec, tt_coderange_glyph ); exec->instruction_trap = FALSE; exec->top = 0; exec->callTop = 0; if ( face->cvt_program_size > 0 ) { error = TT_Goto_CodeRange( exec, tt_coderange_cvt, 0 ); if ( error ) goto End; if ( !size->debug ) error = face->interpreter( exec ); } else error = TT_Err_Ok; size->GS = exec->GS; /* save default graphics state */ End: TT_Save_Context( exec, size ); if ( !size->debug ) TT_Done_Context( exec ); /* debugging instances keep their context */ } #endif /* TT_CONFIG_OPTION_BYTECODE_INTERPRETER */ if ( !error ) size->ttmetrics.valid = TRUE; return error; } #ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS /*************************************************************************/ /* */ /* <Function> */ /* Reset_SBit_Size */ /* */ /* <Description> */ /* Resets a TrueType sbit size when resolutions and character */ /* dimensions have been changed. */ /* */ /* <Input> */ /* size :: A handle to the target size object. */ /* */ static FT_Error Reset_SBit_Size( TT_Size size ) { TT_Face face; FT_Error error = TT_Err_Ok; FT_ULong strike_index; FT_Size_Metrics* metrics; FT_Size_Metrics* sbit_metrics; SFNT_Service sfnt; metrics = &size->metrics; if ( size->strike_index != 0xFFFFU ) return TT_Err_Ok; face = (TT_Face)size->root.face; sfnt = (SFNT_Service)face->sfnt; sbit_metrics = &size->strike_metrics; error = sfnt->set_sbit_strike( face, metrics->x_ppem, metrics->y_ppem, &strike_index ); if ( !error ) { /* XXX: TODO: move this code to the SFNT module where it belongs */ #ifdef FT_OPTIMIZE_MEMORY FT_Byte* strike = face->sbit_table + 8 + strike_index*48; sbit_metrics->ascender = (FT_Char)strike[16] << 6; /* hori.ascender */ sbit_metrics->descender = (FT_Char)strike[17] << 6; /* hori.descender */ /* XXX: Is this correct? */ sbit_metrics->max_advance = ( (FT_Char)strike[22] + /* min_origin_SB */ strike[18] + /* max_width */ (FT_Char)strike[23] /* min_advance_SB */ ) << 6; #else /* !FT_OPTIMIZE_MEMORY */ TT_SBit_Strike strike = face->sbit_strikes + strike_index; sbit_metrics->ascender = strike->hori.ascender << 6; sbit_metrics->descender = strike->hori.descender << 6; /* XXX: Is this correct? */ sbit_metrics->max_advance = ( strike->hori.min_origin_SB + strike->hori.max_width + strike->hori.min_advance_SB ) << 6; #endif /* !FT_OPTIMIZE_MEMORY */ /* XXX: Is this correct? */ sbit_metrics->height = sbit_metrics->ascender - sbit_metrics->descender; sbit_metrics->x_ppem = metrics->x_ppem; sbit_metrics->y_ppem = metrics->y_ppem; size->strike_index = (FT_UInt)strike_index; } else { size->strike_index = 0xFFFFU; sbit_metrics->x_ppem = 0; sbit_metrics->y_ppem = 0; sbit_metrics->ascender = 0; sbit_metrics->descender = 0; sbit_metrics->height = 0; sbit_metrics->max_advance = 0; } return error; } #endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */ /*************************************************************************/ /* */ /* <Function> */ /* tt_size_reset */ /* */ /* <Description> */ /* Resets a TrueType size when resolutions and character dimensions */ /* have been changed. */ /* */ /* <Input> */ /* size :: A handle to the target size object. */ /* */ FT_LOCAL_DEF( FT_Error ) tt_size_reset( TT_Size size ) { FT_Face face; FT_Error error = TT_Err_Ok; face = size->root.face; if ( face->face_flags & FT_FACE_FLAG_SCALABLE ) { if ( !size->ttmetrics.valid ) error = Reset_Outline_Size( size ); if ( error ) return error; } #ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS if ( face->face_flags & FT_FACE_FLAG_FIXED_SIZES ) { if ( size->strike_index == 0xFFFFU ) error = Reset_SBit_Size( size ); if ( !error && !( face->face_flags & FT_FACE_FLAG_SCALABLE ) ) size->root.metrics = size->strike_metrics; } #endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */ if ( face->face_flags & FT_FACE_FLAG_SCALABLE ) return TT_Err_Ok; else return error; } /*************************************************************************/ /* */ /* <Function> */ /* tt_driver_init */ /* */ /* <Description> */ /* Initializes a given TrueType driver object. */ /* */ /* <Input> */ /* driver :: A handle to the target driver object. */ /* */ /* <Return> */ /* FreeType error code. 0 means success. */ /* */ FT_LOCAL_DEF( FT_Error ) tt_driver_init( FT_Module driver ) /* TT_Driver */ { FT_Error error; /* set `extra' in glyph loader */ error = FT_GlyphLoader_CreateExtra( FT_DRIVER( driver )->glyph_loader ); return error; } /*************************************************************************/ /* */ /* <Function> */ /* tt_driver_done */ /* */ /* <Description> */ /* Finalizes a given TrueType driver. */ /* */ /* <Input> */ /* driver :: A handle to the target TrueType driver. */ /* */ FT_LOCAL_DEF( void ) tt_driver_done( FT_Module ttdriver ) /* TT_Driver */ { #ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER TT_Driver driver = (TT_Driver)ttdriver; /* destroy the execution context */ if ( driver->context ) { TT_Destroy_Context( driver->context, driver->root.root.memory ); driver->context = NULL; } #else FT_UNUSED( ttdriver ); #endif } /* END */ --- NEW FILE: ttdriver.c --- /***************************************************************************/ /* */ /* ttdriver.c */ /* */ /* TrueType font driver implementation (body). */ /* */ /* Copyright 1996-2001, 2002, 2003, 2004, 2005 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_INTERNAL_SFNT_H #include FT_TRUETYPE_IDS_H #include FT_SERVICE_XFREE86_NAME_H #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT #include FT_MULTIPLE_MASTERS_H #include FT_SERVICE_MULTIPLE_MASTERS_H #endif #include "ttdriver.h" #include "ttgload.h" #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT #include "ttgxvar.h" #endif #include "tterrors.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_ttdriver /*************************************************************************/ /*************************************************************************/ /*************************************************************************/ /**** ****/ /**** ****/ /**** F A C E S ****/ /**** ****/ /**** ****/ /*************************************************************************/ /*************************************************************************/ /*************************************************************************/ #undef PAIR_TAG #define PAIR_TAG( left, right ) ( ( (FT_ULong)left << 16 ) | \ (FT_ULong)right ) /*************************************************************************/ /* */ /* <Function> */ /* tt_get_kerning */ /* */ /* <Description> */ /* A driver method used to return the kerning vector between two */ /* glyphs of the same face. */ /* */ /* <Input> */ /* face :: A handle to the source face object. */ /* */ /* left_glyph :: The index of the left glyph in the kern pair. */ /* */ /* right_glyph :: The index of the right glyph in the kern pair. */ /* */ /* <Output> */ /* kerning :: The kerning vector. This is in font units for */ /* scalable formats, and in pixels for fixed-sizes */ /* formats. */ /* */ /* <Return> */ /* FreeType error code. 0 means success. */ /* */ /* <Note> */ /* Only horizontal layouts (left-to-right & right-to-left) are */ /* supported by this function. Other layouts, or more sophisticated */ /* kernings, are out of scope of this method (the basic driver */ /* interface is meant to be simple). */ /* */ /* They can be implemented by format-specific interfaces. */ /* */ static FT_Error tt_get_kerning( FT_Face ttface, /* TT_Face */ FT_UInt left_glyph, FT_UInt right_glyph, FT_Vector* kerning ) { TT_Face face = (TT_Face)ttface; SFNT_Service sfnt = (SFNT_Service)face->sfnt; kerning->x = 0; kerning->y = 0; if ( sfnt ) kerning->x = sfnt->get_kerning( face, left_glyph, right_glyph ); return 0; } #undef PAIR_TAG /*************************************************************************/ /*************************************************************************/ /*************************************************************************/ /**** ****/ /**** ****/ /**** S I Z E S ****/ /**** ****/ /**** ****/ /*************************************************************************/ /*************************************************************************/ /*************************************************************************/ /*************************************************************************/ /* */ /* <Function> */ /* Set_Char_Sizes */ /* */ /* <Description> */ /* A driver method used to reset a size's character sizes (horizontal */ /* and vertical) expressed in fractional points. */ /* */ /* <Input> */ /* char_width :: The character width expressed in 26.6 */ /* fractional points. */ /* */ /* char_height :: The character height expressed in 26.6 */ /* fractional points. */ /* */ /* horz_resolution :: The horizontal resolution of the output device. */ /* */ /* vert_resolution :: The vertical resolution of the output device. */ /* */ /* <InOut> */ /* size :: A handle to the target size object. */ /* */ /* <Return> */ /* FreeType error code. 0 means success. */ /* */ static FT_Error Set_Char_Sizes( FT_Size ttsize, /* TT_Size */ FT_F26Dot6 char_width, FT_F26Dot6 char_height, FT_UInt horz_resolution, FT_UInt vert_resolution ) { TT_Size size = (TT_Size)ttsize; FT_Size_Metrics* metrics = &size->root.metrics; FT_Size_Metrics* metrics2 = &size->metrics; TT_Face face = (TT_Face)size->root.face; FT_Long dim_x, dim_y; *metrics2 = *metrics; /* This bit flag, when set, indicates that the pixel size must be */ /* truncated to an integer. Nearly all TrueType fonts have this */ /* bit set, as hinting won't work really well otherwise. */ /* */ if ( ( face->header.Flags & 8 ) != 0 ) { /* we need to use rounding in the following computations. Otherwise, * the resulting hinted outlines will be very slightly distorted */ dim_x = ( ( char_width * horz_resolution + (36+32*72) ) / 72 ) & ~63; dim_y = ( ( char_height * vert_resolution + (36+32*72) ) / 72 ) & ~63; } else { dim_x = ( ( char_width * horz_resolution + 36 ) / 72 ); dim_y = ( ( char_height * vert_resolution + 36 ) / 72 ); } /* we only modify "metrics2", not "metrics", so these changes have */ /* no effect on the result of the auto-hinter when it is used */ /* */ metrics2->x_ppem = (FT_UShort)( dim_x >> 6 ); metrics2->y_ppem = (FT_UShort)( dim_y >> 6 ); metrics2->x_scale = FT_DivFix( dim_x, face->root.units_per_EM ); metrics2->y_scale = FT_DivFix( dim_y, face->root.units_per_EM ); size->ttmetrics.valid = FALSE; #ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS size->strike_index = 0xFFFFU; #endif return tt_size_reset( size ); } /*************************************************************************/ /* */ /* <Function> */ /* Set_Pixel_Sizes */ /* */ /* <Description> */ /* A driver method used to reset a size's character sizes (horizontal */ /* and vertical) expressed in integer pixels. */ /* */ /* <InOut> */ /* size :: A handle to the target size object. */ /* */ /* <Return> */ /* FreeType error code. 0 means success. */ /* */ static FT_Error Set_Pixel_Sizes( FT_Size ttsize, /* TT_Size */ FT_UInt pixel_width, FT_UInt pixel_height ) { TT_Size size = (TT_Size)ttsize; FT_UNUSED( pixel_width ); FT_UNUSED( pixel_height ); /* many things have been pre-computed by the base layer */ size->metrics = size->root.metrics; size->ttmetrics.valid = FALSE; #ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS size->strike_index = 0xFFFFU; #endif return tt_size_reset( size ); } /*************************************************************************/ /* */ /* <Function> */ /* Load_Glyph */ /* */ /* <Description> */ /* A driver method used to load a glyph within a given glyph slot. */ /* */ /* <Input> */ /* slot :: A handle to the target slot object where the glyph */ /* will be loaded. */ /* */ /* size :: A handle to the source face size at which the glyph */ /* must be scaled, loaded, etc. */ /* */ /* glyph_index :: The index of the glyph in the font file. */ /* */ /* load_flags :: A flag indicating what to load for this glyph. The */ /* FTLOAD_??? constants can be used to control the */ /* glyph loading process (e.g., whether the outline */ /* should be scaled, whether to load bitmaps or not, */ /* whether to hint the outline, etc). */ /* */ /* <Return> */ /* FreeType error code. 0 means success. */ /* */ static FT_Error Load_Glyph( FT_GlyphSlot ttslot, /* TT_GlyphSlot */ FT_Size ttsize, /* TT_Size */ FT_UInt glyph_index, FT_Int32 load_flags ) { TT_GlyphSlot slot = (TT_GlyphSlot)ttslot; TT_Size size = (TT_Size)ttsize; FT_Error error; if ( !slot ) return TT_Err_Invalid_Slot_Handle; /* check whether we want a scaled outline or bitmap */ if ( !size ) load_flags |= FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING; if ( load_flags & FT_LOAD_NO_SCALE ) size = NULL; /* reset the size object if necessary */ if ( size ) { /* these two object must have the same parent */ if ( size->root.face != slot->face ) return TT_Err_Invalid_Face_Handle; if ( !size->ttmetrics.valid ) { if ( FT_SET_ERROR( tt_size_reset( size ) ) ) return error; } } /* now load the glyph outline if necessary */ error = TT_Load_Glyph( size, slot, glyph_index, load_flags ); /* force drop-out mode to 2 - irrelevant now */ /* slot->outline.dropout_mode = 2; */ return error; } /*************************************************************************/ /*************************************************************************/ /*************************************************************************/ /**** ****/ /**** ****/ /**** D R I V E R I N T E R F A C E ****/ /**** ****/ /**** ****/ /*************************************************************************/ /*************************************************************************/ /*************************************************************************/ #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT static const FT_Service_MultiMastersRec tt_service_gx_multi_masters = { (FT_Get_MM_Func) NULL, (FT_Set_MM_Design_Func) NULL, (FT_Set_MM_Blend_Func) TT_Set_MM_Blend, (FT_Get_MM_Var_Func) TT_Get_MM_Var, (FT_Set_Var_Design_Func)TT_Set_Var_Design }; #endif static const FT_ServiceDescRec tt_services[] = { { FT_SERVICE_ID_XF86_NAME, FT_XF86_FORMAT_TRUETYPE }, #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT { FT_SERVICE_ID_MULTI_MASTERS, &tt_service_gx_multi_masters }, #endif { NULL, NULL } }; FT_CALLBACK_DEF( FT_Module_Interface ) tt_get_interface( FT_Module driver, /* TT_Driver */ const char* tt_interface ) { FT_Module_Interface result; FT_Module sfntd; SFNT_Service sfnt; result = ft_service_list_lookup( tt_services, tt_interface ); if ( result != NULL ) return result; /* only return the default interface from the SFNT module */ sfntd = FT_Get_Module( driver->library, "sfnt" ); if ( sfntd ) { sfnt = (SFNT_Service)( sfntd->clazz->module_interface ); if ( sfnt ) return sfnt->get_interface( driver, tt_interface ); } return 0; } /* The FT_DriverInterface structure is defined in ftdriver.h. */ FT_CALLBACK_TABLE_DEF const FT_Driver_ClassRec tt_driver_class = { { FT_MODULE_FONT_DRIVER | FT_MODULE_DRIVER_SCALABLE | #ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER FT_MODULE_DRIVER_HAS_HINTER, #else 0, #endif sizeof ( TT_DriverRec ), "truetype", /* driver name */ 0x10000L, /* driver version == 1.0 */ 0x20000L, /* driver requires FreeType 2.0 or above */ (void*)0, /* driver specific interface */ tt_driver_init, tt_driver_done, tt_get_interface, }, sizeof ( TT_FaceRec ), sizeof ( TT_SizeRec ), sizeof ( FT_GlyphSlotRec ), tt_face_init, tt_face_done, tt_size_init, tt_size_done, 0, /* FT_Slot_InitFunc */ 0, /* FT_Slot_DoneFunc */ Set_Char_Sizes, Set_Pixel_Sizes, Load_Glyph, tt_get_kerning, 0, /* FT_Face_AttachFunc */ 0 /* FT_Face_GetAdvancesFunc */ }; /* END */ --- NEW FILE: ttgxvar.c --- /***************************************************************************/ /* */ /* ttgxvar.c */ /* */ /* TrueType GX Font Variation loader */ /* */ /* Copyright 2004, 2005 by */ /* David Turner, Robert Wilhelm, Werner Lemberg, and George Williams. */ /* */ /* 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. */ /* */ /***************************************************************************/ /***************************************************************************/ [...1495 lines suppressed...] FT_FREE( blend->normalizedcoords ); FT_FREE( blend->mmvar ); if ( blend->avar_segment != NULL ) { for ( i = 0; i < blend->num_axis; ++i ) FT_FREE( blend->avar_segment[i].correspondence ); FT_FREE( blend->avar_segment ); } FT_FREE( blend->tuplecoords ); FT_FREE( blend->glyphoffsets ); FT_FREE( blend ); } } #endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */ /* END */ --- NEW FILE: ttgload.c --- /***************************************************************************/ /* */ /* ttgload.c */ /* */ /* TrueType Glyph Loader (body). */ /* */ /* Copyright 1996-2001, 2002, 2003, 2004, 2005 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> [...2091 lines suppressed...] #ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER if ( !size || !size->debug ) TT_Done_Context( loader.exec ); #endif /* TT_CONFIG_OPTION_BYTECODE_INTERPRETER */ /* Set the `high precision' bit flag. */ /* This is _critical_ to get correct output for monochrome */ /* TrueType glyphs at all sizes using the bytecode interpreter. */ /* */ if ( size && size->root.metrics.y_ppem < 24 ) glyph->outline.flags |= FT_OUTLINE_HIGH_PRECISION; Exit: return error; } /* END */ --- NEW FILE: ttpload.c --- /***************************************************************************/ /* */ /* ttpload.c */ /* */ /* TrueType glyph data/program tables loader (body). */ /* */ /* Copyright 1996-2001, 2002, 2004, 2005 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 #includ... [truncated message content] |
Update of /cvsroot/roadmap/roadmap_editor/src/freetype/src/autofit In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv22848/src/autofit Added Files: afangles.c afdummy.c afglobal.c afhints.c aflatin.c afloader.c afmodule.c autofit.c Log Message: Import freetype sources. --- NEW FILE: afhints.c --- /***************************************************************************/ /* */ /* afhints.c */ /* */ /* Auto-fitter hinting routines (body). */ /* */ /* Copyright 2003, 2004, 2005 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 "afhints.h" [...1051 lines suppressed...] cur_touched, first_touched ); } } } /* now save the interpolated values back to x/y */ if ( dim == AF_DIMENSION_HORZ ) { for ( point = points; point < point_limit; point++ ) point->x = point->u; } else { for ( point = points; point < point_limit; point++ ) point->y = point->u; } } /* END */ --- NEW FILE: afmodule.c --- /***************************************************************************/ /* */ /* afmodule.c */ /* */ /* Auto-fitter module implementation (body). */ /* */ /* Copyright 2003, 2004, 2005 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 "afmodule.h" #include "afloader.h" #include FT_INTERNAL_OBJECTS_H typedef struct FT_AutofitterRec_ { FT_ModuleRec root; AF_LoaderRec loader[1]; } FT_AutofitterRec, *FT_Autofitter; FT_CALLBACK_DEF( FT_Error ) af_autofitter_init( FT_Autofitter module ) { return af_loader_init( module->loader, module->root.library->memory ); } FT_CALLBACK_DEF( void ) af_autofitter_done( FT_Autofitter module ) { af_loader_done( module->loader ); } FT_CALLBACK_DEF( FT_Error ) af_autofitter_load_glyph( FT_Autofitter module, FT_GlyphSlot slot, FT_Size size, FT_UInt glyph_index, FT_Int32 load_flags ) { FT_UNUSED( size ); return af_loader_load_glyph( module->loader, slot->face, glyph_index, load_flags ); } FT_CALLBACK_TABLE_DEF const FT_AutoHinter_ServiceRec af_autofitter_service = { NULL, NULL, NULL, (FT_AutoHinter_GlyphLoadFunc)af_autofitter_load_glyph }; FT_CALLBACK_TABLE_DEF const FT_Module_Class autofit_module_class = { FT_MODULE_HINTER, sizeof ( FT_AutofitterRec ), "autofitter", 0x10000L, /* version 1.0 of the autofitter */ 0x20000L, /* requires FreeType 2.0 or above */ (const void*)&af_autofitter_service, (FT_Module_Constructor)af_autofitter_init, (FT_Module_Destructor) af_autofitter_done, (FT_Module_Requester) NULL }; /* END */ --- NEW FILE: afglobal.c --- /***************************************************************************/ /* */ /* afglobal.c */ /* */ /* Auto-fitter routines to compute global hinting values (body). */ /* */ /* Copyright 2003, 2004, 2005 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 "afglobal.h" #include "afdummy.h" #include "aflatin.h" #include "aferrors.h" /* populate this list when you add new scripts */ static AF_ScriptClass const af_script_classes[] = { &af_dummy_script_class, &af_latin_script_class, NULL /* do not remove */ }; /* index of default script in `af_script_classes' */ #define AF_SCRIPT_LIST_DEFAULT 1 /* indicates an uncovered glyph */ #define AF_SCRIPT_LIST_NONE 255 /* * Note that glyph_scripts[] is used to map each glyph into * an index into the `af_script_classes' array. * */ typedef struct AF_FaceGlobalsRec_ { FT_Face face; FT_UInt glyph_count; /* same as face->num_glyphs */ FT_Byte* glyph_scripts; AF_ScriptMetrics metrics[AF_SCRIPT_MAX]; } AF_FaceGlobalsRec; /* Compute the script index of each glyph within a given face. */ static FT_Error af_face_globals_compute_script_coverage( AF_FaceGlobals globals ) { FT_Error error = AF_Err_Ok; FT_Face face = globals->face; FT_CharMap old_charmap = face->charmap; FT_Byte* gscripts = globals->glyph_scripts; FT_UInt ss; /* the value 255 means `uncovered glyph' */ FT_MEM_SET( globals->glyph_scripts, AF_SCRIPT_LIST_NONE, globals->glyph_count ); error = FT_Select_Charmap( face, FT_ENCODING_UNICODE ); if ( error ) { /* * Ignore this error; we simply use Latin as the standard * script. XXX: Shouldn't we rather disable hinting? */ error = AF_Err_Ok; goto Exit; } /* scan each script in a Unicode charmap */ for ( ss = 0; af_script_classes[ss]; ss++ ) { AF_ScriptClass clazz = af_script_classes[ss]; AF_Script_UniRange range; if ( clazz->script_uni_ranges == NULL ) continue; /* * Scan all unicode points in the range and set the corresponding * glyph script index. */ for ( range = clazz->script_uni_ranges; range->first != 0; range++ ) { FT_ULong charcode = range->first; FT_UInt gindex; gindex = FT_Get_Char_Index( face, charcode ); if ( gindex != 0 && gindex < globals->glyph_count && gscripts[gindex] == AF_SCRIPT_LIST_NONE ) { gscripts[gindex] = (FT_Byte)ss; } for (;;) { charcode = FT_Get_Next_Char( face, charcode, &gindex ); if ( gindex == 0 || charcode > range->last ) break; if ( gindex < globals->glyph_count && gscripts[gindex] == AF_SCRIPT_LIST_NONE ) { gscripts[gindex] = (FT_Byte)ss; } } } } Exit: /* * By default, all uncovered glyphs are set to the latin script. * XXX: Shouldnt' we disable hinting or do something similar? */ { FT_UInt nn; for ( nn = 0; nn < globals->glyph_count; nn++ ) { if ( gscripts[nn] == AF_SCRIPT_LIST_NONE ) gscripts[nn] = AF_SCRIPT_LIST_DEFAULT; } } FT_Set_Charmap( face, old_charmap ); return error; } FT_LOCAL_DEF( FT_Error ) af_face_globals_new( FT_Face face, AF_FaceGlobals *aglobals ) { FT_Error error; FT_Memory memory; AF_FaceGlobals globals; memory = face->memory; if ( !FT_ALLOC( globals, sizeof ( *globals ) + face->num_glyphs * sizeof ( FT_Byte ) ) ) { globals->face = face; globals->glyph_count = face->num_glyphs; globals->glyph_scripts = (FT_Byte*)( globals + 1 ); error = af_face_globals_compute_script_coverage( globals ); if ( error ) { af_face_globals_free( globals ); globals = NULL; } } *aglobals = globals; return error; } FT_LOCAL_DEF( void ) af_face_globals_free( AF_FaceGlobals globals ) { if ( globals ) { FT_Memory memory = globals->face->memory; FT_UInt nn; for ( nn = 0; nn < AF_SCRIPT_MAX; nn++ ) { if ( globals->metrics[nn] ) { AF_ScriptClass clazz = af_script_classes[nn]; FT_ASSERT( globals->metrics[nn]->clazz == clazz ); if ( clazz->script_metrics_done ) clazz->script_metrics_done( globals->metrics[nn] ); FT_FREE( globals->metrics[nn] ); } } globals->glyph_count = 0; globals->glyph_scripts = NULL; /* no need to free this one! */ globals->face = NULL; FT_FREE( globals ); } } FT_LOCAL_DEF( FT_Error ) af_face_globals_get_metrics( AF_FaceGlobals globals, FT_UInt gindex, AF_ScriptMetrics *ametrics ) { AF_ScriptMetrics metrics = NULL; FT_UInt gidx; AF_ScriptClass clazz; FT_Error error = AF_Err_Ok; if ( gindex >= globals->glyph_count ) { error = AF_Err_Invalid_Argument; goto Exit; } gidx = globals->glyph_scripts[gindex]; clazz = af_script_classes[gidx]; metrics = globals->metrics[clazz->script]; if ( metrics == NULL ) { /* create the global metrics object when needed */ FT_Memory memory = globals->face->memory; if ( FT_ALLOC( metrics, clazz->script_metrics_size ) ) goto Exit; metrics->clazz = clazz; if ( clazz->script_metrics_init ) { error = clazz->script_metrics_init( metrics, globals->face ); if ( error ) { if ( clazz->script_metrics_done ) clazz->script_metrics_done( metrics ); FT_FREE( metrics ); goto Exit; } } globals->metrics[clazz->script] = metrics; } Exit: *ametrics = metrics; return error; } /* END */ --- NEW FILE: afloader.c --- /***************************************************************************/ /* */ /* afloader.c */ /* */ /* Auto-fitter glyph loading routines (body). */ /* */ /* Copyright 2003, 2004, 2005 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 "afloader.h" #include "afhints.h" #include "afglobal.h" #include "aflatin.h" #include "aferrors.h" FT_LOCAL_DEF( FT_Error ) af_loader_init( AF_Loader loader, FT_Memory memory ) { FT_Error error; FT_ZERO( loader ); af_glyph_hints_init( &loader->hints, memory ); error = FT_GlyphLoader_New( memory, &loader->gloader ); if ( !error ) { error = FT_GlyphLoader_CreateExtra( loader->gloader ); if ( error ) { FT_GlyphLoader_Done( loader->gloader ); loader->gloader = NULL; } } return error; } FT_LOCAL_DEF( FT_Error ) af_loader_reset( AF_Loader loader, FT_Face face ) { FT_Error error = AF_Err_Ok; loader->face = face; loader->globals = (AF_FaceGlobals)face->autohint.data; FT_GlyphLoader_Rewind( loader->gloader ); if ( loader->globals == NULL ) { error = af_face_globals_new( face, &loader->globals ); if ( !error ) { face->autohint.data = (FT_Pointer)loader->globals; face->autohint.finalizer = (FT_Generic_Finalizer)af_face_globals_free; } } return error; } FT_LOCAL_DEF( void ) af_loader_done( AF_Loader loader ) { af_glyph_hints_done( &loader->hints ); loader->face = NULL; loader->globals = NULL; FT_GlyphLoader_Done( loader->gloader ); loader->gloader = NULL; } static FT_Error af_loader_load_g( AF_Loader loader, AF_Scaler scaler, FT_UInt glyph_index, FT_Int32 load_flags, FT_UInt depth ) { FT_Error error; FT_Face face = loader->face; FT_GlyphLoader gloader = loader->gloader; AF_ScriptMetrics metrics = loader->metrics; AF_GlyphHints hints = &loader->hints; FT_GlyphSlot slot = face->glyph; FT_Slot_Internal internal = slot->internal; error = FT_Load_Glyph( face, glyph_index, load_flags ); if ( error ) goto Exit; loader->transformed = internal->glyph_transformed; if ( loader->transformed ) { FT_Matrix inverse; loader->trans_matrix = internal->glyph_matrix; loader->trans_delta = internal->glyph_delta; inverse = loader->trans_matrix; FT_Matrix_Invert( &inverse ); FT_Vector_Transform( &loader->trans_delta, &inverse ); } /* set linear metrics */ slot->linearHoriAdvance = slot->metrics.horiAdvance; slot->linearVertAdvance = slot->metrics.vertAdvance; switch ( slot->format ) { case FT_GLYPH_FORMAT_OUTLINE: /* translate the loaded glyph when an internal transform is needed */ if ( loader->transformed ) FT_Outline_Translate( &slot->outline, loader->trans_delta.x, loader->trans_delta.y ); /* copy the outline points in the loader's current */ /* extra points which is used to keep original glyph coordinates */ error = FT_GlyphLoader_CheckPoints( gloader, slot->outline.n_points + 4, slot->outline.n_contours ); if ( error ) goto Exit; FT_ARRAY_COPY( gloader->current.outline.points, slot->outline.points, slot->outline.n_points ); FT_ARRAY_COPY( gloader->current.extra_points, slot->outline.points, slot->outline.n_points ); FT_ARRAY_COPY( gloader->current.outline.contours, slot->outline.contours, slot->outline.n_contours ); FT_ARRAY_COPY( gloader->current.outline.tags, slot->outline.tags, slot->outline.n_points ); gloader->current.outline.n_points = slot->outline.n_points; gloader->current.outline.n_contours = slot->outline.n_contours; /* compute original horizontal phantom points (and ignore */ /* vertical ones) */ loader->pp1.x = hints->x_delta; loader->pp1.y = hints->y_delta; loader->pp2.x = FT_MulFix( slot->metrics.horiAdvance, hints->x_scale ) + hints->x_delta; loader->pp2.y = hints->y_delta; /* be sure to check for spacing glyphs */ if ( slot->outline.n_points == 0 ) goto Hint_Metrics; /* now load the slot image into the auto-outline and run the */ /* automatic hinting process */ metrics->clazz->script_hints_apply( hints, &gloader->current.outline, metrics ); /* we now need to hint the metrics according to the change in */ /* width/positioning that occured during the hinting process */ { FT_Pos old_advance, old_rsb, old_lsb, new_lsb; FT_Pos pp1x_uh, pp2x_uh; AF_AxisHints axis = &hints->axis[AF_DIMENSION_HORZ]; AF_Edge edge1 = axis->edges; /* leftmost edge */ AF_Edge edge2 = edge1 + axis->num_edges - 1; /* rightmost edge */ if ( axis->num_edges > 1 ) { old_advance = loader->pp2.x; old_rsb = old_advance - edge2->opos; old_lsb = edge1->opos; new_lsb = edge1->pos; /* remember unhinted values to later account */ /* for rounding errors */ pp1x_uh = new_lsb - old_lsb; pp2x_uh = edge2->pos + old_rsb; /* prefer too much space over too little space */ /* for very small sizes */ if ( old_lsb < 24 ) pp1x_uh -= 5; if ( old_rsb < 24 ) pp2x_uh += 5; loader->pp1.x = FT_PIX_ROUND( pp1x_uh ); loader->pp2.x = FT_PIX_ROUND( pp2x_uh ); slot->lsb_delta = loader->pp1.x - pp1x_uh; slot->rsb_delta = loader->pp2.x - pp2x_uh; #if 0 /* try to fix certain bad advance computations */ if ( loader->pp2.x + loader->pp1.x == edge2->pos && old_rsb > 4 ) loader->pp2.x += 64; #endif } else { loader->pp1.x = FT_PIX_ROUND( loader->pp1.x ); loader->pp2.x = FT_PIX_ROUND( loader->pp2.x ); } } /* good, we simply add the glyph to our loader's base */ FT_GlyphLoader_Add( gloader ); break; case FT_GLYPH_FORMAT_COMPOSITE: { FT_UInt nn, num_subglyphs = slot->num_subglyphs; FT_UInt num_base_subgs, start_point; FT_SubGlyph subglyph; start_point = gloader->base.outline.n_points; /* first of all, copy the subglyph descriptors in the glyph loader */ error = FT_GlyphLoader_CheckSubGlyphs( gloader, num_subglyphs ); if ( error ) goto Exit; FT_ARRAY_COPY( gloader->current.subglyphs, slot->subglyphs, num_subglyphs ); gloader->current.num_subglyphs = num_subglyphs; num_base_subgs = gloader->base.num_subglyphs; /* now, read each subglyph independently */ for ( nn = 0; nn < num_subglyphs; nn++ ) { FT_Vector pp1, pp2; FT_Pos x, y; FT_UInt num_points, num_new_points, num_base_points; /* gloader.current.subglyphs can change during glyph loading due */ /* to re-allocation -- we must recompute the current subglyph on */ /* each iteration */ subglyph = gloader->base.subglyphs + num_base_subgs + nn; pp1 = loader->pp1; pp2 = loader->pp2; num_base_points = gloader->base.outline.n_points; error = af_loader_load_g( loader, scaler, subglyph->index, load_flags, depth + 1 ); if ( error ) goto Exit; /* recompute subglyph pointer */ subglyph = gloader->base.subglyphs + num_base_subgs + nn; if ( subglyph->flags & FT_SUBGLYPH_FLAG_USE_MY_METRICS ) { pp1 = loader->pp1; pp2 = loader->pp2; } else { loader->pp1 = pp1; loader->pp2 = pp2; } num_points = gloader->base.outline.n_points; num_new_points = num_points - num_base_points; /* now perform the transform required for this subglyph */ if ( subglyph->flags & ( FT_SUBGLYPH_FLAG_SCALE | FT_SUBGLYPH_FLAG_XY_SCALE | FT_SUBGLYPH_FLAG_2X2 ) ) { FT_Vector* cur = gloader->base.outline.points + num_base_points; FT_Vector* org = gloader->base.extra_points + num_base_points; FT_Vector* limit = cur + num_new_points; for ( ; cur < limit; cur++, org++ ) { FT_Vector_Transform( cur, &subglyph->transform ); FT_Vector_Transform( org, &subglyph->transform ); } } /* apply offset */ if ( !( subglyph->flags & FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES ) ) { FT_Int k = subglyph->arg1; FT_UInt l = subglyph->arg2; FT_Vector* p1; FT_Vector* p2; if ( start_point + k >= num_base_points || l >= (FT_UInt)num_new_points ) { error = AF_Err_Invalid_Composite; goto Exit; } l += num_base_points; /* for now, only use the current point coordinates; */ /* we may consider another approach in the near future */ p1 = gloader->base.outline.points + start_point + k; p2 = gloader->base.outline.points + start_point + l; x = p1->x - p2->x; y = p1->y - p2->y; } else { x = FT_MulFix( subglyph->arg1, hints->x_scale ) + hints->x_delta; y = FT_MulFix( subglyph->arg2, hints->y_scale ) + hints->y_delta; x = FT_PIX_ROUND( x ); y = FT_PIX_ROUND( y ); } { FT_Outline dummy = gloader->base.outline; dummy.points += num_base_points; dummy.n_points = (short)num_new_points; FT_Outline_Translate( &dummy, x, y ); } } } break; default: /* we don't support other formats (yet?) */ error = AF_Err_Unimplemented_Feature; } Hint_Metrics: if ( depth == 0 ) { FT_BBox bbox; /* transform the hinted outline if needed */ if ( loader->transformed ) FT_Outline_Transform( &gloader->base.outline, &loader->trans_matrix ); /* we must translate our final outline by -pp1.x and compute */ /* the new metrics */ if ( loader->pp1.x ) FT_Outline_Translate( &gloader->base.outline, -loader->pp1.x, 0 ); FT_Outline_Get_CBox( &gloader->base.outline, &bbox ); bbox.xMin = FT_PIX_FLOOR( bbox.xMin ); bbox.yMin = FT_PIX_FLOOR( bbox.yMin ); bbox.xMax = FT_PIX_CEIL( bbox.xMax ); bbox.yMax = FT_PIX_CEIL( bbox.yMax ); slot->metrics.width = bbox.xMax - bbox.xMin; slot->metrics.height = bbox.yMax - bbox.yMin; slot->metrics.horiBearingX = bbox.xMin; slot->metrics.horiBearingY = bbox.yMax; /* for mono-width fonts (like Andale, Courier, etc.) we need */ /* to keep the original rounded advance width */ #if 0 if ( !FT_IS_FIXED_WIDTH( slot->face ) ) slot->metrics.horiAdvance = loader->pp2.x - loader->pp1.x; else slot->metrics.horiAdvance = FT_MulFix( slot->metrics.horiAdvance, x_scale ); #else if ( !FT_IS_FIXED_WIDTH( slot->face ) ) slot->metrics.horiAdvance = loader->pp2.x - loader->pp1.x; else slot->metrics.horiAdvance = FT_MulFix( slot->metrics.horiAdvance, metrics->scaler.x_scale ); #endif slot->metrics.horiAdvance = FT_PIX_ROUND( slot->metrics.horiAdvance ); /* now copy outline into glyph slot */ FT_GlyphLoader_Rewind( internal->loader ); error = FT_GlyphLoader_CopyPoints( internal->loader, gloader ); if ( error ) goto Exit; slot->outline = internal->loader->base.outline; slot->format = FT_GLYPH_FORMAT_OUTLINE; } #ifdef DEBUG_HINTER af_debug_hinter = hinter; #endif Exit: return error; } FT_LOCAL_DEF( FT_Error ) af_loader_load_glyph( AF_Loader loader, FT_Face face, FT_UInt gindex, FT_UInt32 load_flags ) { FT_Error error; FT_Size size = face->size; AF_ScalerRec scaler; if ( !size ) return AF_Err_Invalid_Argument; FT_ZERO( &scaler ); scaler.face = face; scaler.x_scale = size->metrics.x_scale; scaler.x_delta = 0; /* XXX: TODO: add support for sub-pixel hinting */ scaler.y_scale = size->metrics.y_scale; scaler.y_delta = 0; /* XXX: TODO: add support for sub-pixel hinting */ scaler.render_mode = FT_LOAD_TARGET_MODE( load_flags ); scaler.flags = 0; /* XXX: fix this */ error = af_loader_reset( loader, face ); if ( !error ) { AF_ScriptMetrics metrics; error = af_face_globals_get_metrics( loader->globals, gindex, &metrics ); if ( !error ) { loader->metrics = metrics; if ( metrics->clazz->script_metrics_scale ) metrics->clazz->script_metrics_scale( metrics, &scaler ); else metrics->scaler = scaler; load_flags |= FT_LOAD_NO_SCALE | FT_LOAD_IGNORE_TRANSFORM; load_flags &= ~FT_LOAD_RENDER; error = metrics->clazz->script_hints_init( &loader->hints, metrics ); if ( error ) goto Exit; error = af_loader_load_g( loader, &scaler, gindex, load_flags, 0 ); } } Exit: return error; } /* END */ --- NEW FILE: aflatin.c --- /***************************************************************************/ /* */ /* aflatin.c */ /* */ /* Auto-fitter hinting routines for latin script (body). */ /* */ /* Copyright 2003, 2004, 2005 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 "aflatin.h" [...1937 lines suppressed...] FT_CALLBACK_TABLE_DEF const AF_ScriptClassRec af_latin_script_class = { AF_SCRIPT_LATIN, af_latin_uniranges, sizeof( AF_LatinMetricsRec ), (AF_Script_InitMetricsFunc) af_latin_metrics_init, (AF_Script_ScaleMetricsFunc)af_latin_metrics_scale, (AF_Script_DoneMetricsFunc) NULL, (AF_Script_InitHintsFunc) af_latin_hints_init, (AF_Script_ApplyHintsFunc) af_latin_hints_apply }; /* END */ --- NEW FILE: autofit.c --- /***************************************************************************/ /* */ /* autofit.c */ /* */ /* Auto-fitter module (body). */ /* */ /* Copyright 2003, 2004, 2005 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. */ /* */ /***************************************************************************/ #define FT_MAKE_OPTION_SINGLE_OBJECT #include <ft2build.h> #include "afangles.c" #include "afglobal.c" #include "afhints.c" #include "afdummy.c" #include "aflatin.c" #include "afloader.c" #include "afmodule.c" /* END */ --- NEW FILE: afangles.c --- /***************************************************************************/ /* */ /* afangles.c */ /* */ /* Routines used to compute vector angles with limited accuracy */ /* and very high speed. It also contains sorting routines (body). */ /* */ /* Copyright 2003, 2004, 2005 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 "aftypes.h" /* * a python script used to generate the following table * import sys, math units = 256 scale = units/math.pi comma = "" print "" print "table of arctan( 1/2^n ) for PI = " + repr( units / 65536.0 ) + " units" r = [-1] + range( 32 ) for n in r: if n >= 0: x = 1.0 / ( 2.0 ** n ) # tangent value else: x = 2.0 ** ( -n ) angle = math.atan( x ) # arctangent angle2 = angle * scale # arctangent in FT_Angle units # determine which integer value for angle gives the best tangent lo = int( angle2 ) hi = lo + 1 tlo = math.tan( lo / scale ) thi = math.tan( hi / scale ) errlo = abs( tlo - x ) errhi = abs( thi - x ) angle2 = hi if errlo < errhi: angle2 = lo if angle2 <= 0: break sys.stdout.write( comma + repr( int( angle2 ) ) ) comma = ", " * * end of python script */ /* this table was generated for AF_ANGLE_PI = 256 */ #define AF_ANGLE_MAX_ITERS 8 #define AF_TRIG_MAX_ITERS 8 static const FT_Fixed af_angle_arctan_table[9] = { 90, 64, 38, 20, 10, 5, 3, 1, 1 }; static FT_Int af_angle_prenorm( FT_Vector* vec ) { FT_Fixed x, y, z; FT_Int shift; x = vec->x; y = vec->y; z = ( ( x >= 0 ) ? x : - x ) | ( (y >= 0) ? y : -y ); shift = 0; if ( z < ( 1L << 27 ) ) { do { shift++; z <<= 1; } while ( z < ( 1L << 27 ) ); vec->x = x << shift; vec->y = y << shift; } else if ( z > ( 1L << 28 ) ) { do { shift++; z >>= 1; } while ( z > ( 1L << 28 ) ); vec->x = x >> shift; vec->y = y >> shift; shift = -shift; } return shift; } static void af_angle_pseudo_polarize( FT_Vector* vec ) { FT_Fixed theta; FT_Fixed yi, i; FT_Fixed x, y; const FT_Fixed *arctanptr; x = vec->x; y = vec->y; /* Get the vector into the right half plane */ theta = 0; if ( x < 0 ) { x = -x; y = -y; theta = AF_ANGLE_PI; } if ( y > 0 ) theta = -theta; arctanptr = af_angle_arctan_table; if ( y < 0 ) { /* Rotate positive */ yi = y + ( x << 1 ); x = x - ( y << 1 ); y = yi; theta -= *arctanptr++; /* Subtract angle */ } else { /* Rotate negative */ yi = y - ( x << 1 ); x = x + ( y << 1 ); y = yi; theta += *arctanptr++; /* Add angle */ } i = 0; do { if ( y < 0 ) { /* Rotate positive */ yi = y + ( x >> i ); x = x - ( y >> i ); y = yi; theta -= *arctanptr++; } else { /* Rotate negative */ yi = y - ( x >> i ); x = x + ( y >> i ); y = yi; theta += *arctanptr++; } } while ( ++i < AF_TRIG_MAX_ITERS ); #if 0 /* round theta */ if ( theta >= 0 ) theta = FT_PAD_ROUND( theta, 2 ); else theta = -FT_PAD_ROUND( -theta, 2 ); #endif vec->x = x; vec->y = theta; } /* cf. documentation in fttrigon.h */ FT_LOCAL_DEF( AF_Angle ) af_angle_atan( FT_Fixed dx, FT_Fixed dy ) { FT_Vector v; if ( dx == 0 && dy == 0 ) return 0; v.x = dx; v.y = dy; af_angle_prenorm( &v ); af_angle_pseudo_polarize( &v ); return v.y; } FT_LOCAL_DEF( AF_Angle ) af_angle_diff( AF_Angle angle1, AF_Angle angle2 ) { AF_Angle delta = angle2 - angle1; delta %= AF_ANGLE_2PI; if ( delta < 0 ) delta += AF_ANGLE_2PI; if ( delta > AF_ANGLE_PI ) delta -= AF_ANGLE_2PI; return delta; } FT_LOCAL_DEF( void ) af_sort_pos( FT_UInt count, FT_Pos* table ) { FT_UInt i, j; FT_Pos swap; for ( i = 1; i < count; i++ ) { for ( j = i; j > 0; j-- ) { if ( table[j] > table[j - 1] ) break; swap = table[j]; table[j] = table[j - 1]; table[j - 1] = swap; } } } FT_LOCAL_DEF( void ) af_sort_widths( FT_UInt count, AF_Width table ) { FT_UInt i, j; AF_WidthRec swap; for ( i = 1; i < count; i++ ) { for ( j = i; j > 0; j-- ) { if ( table[j].org > table[j - 1].org ) break; swap = table[j]; table[j] = table[j - 1]; table[j - 1] = swap; } } } #ifdef TEST #include <stdio.h> #include <math.h> int main( void ) { int angle; int dist; for ( dist = 100; dist < 1000; dist++ ) { for ( angle = AF_ANGLE_PI; angle < AF_ANGLE_2PI * 4; angle++ ) { double a = ( angle * 3.1415926535 ) / ( 1.0 * AF_ANGLE_PI ); int dx, dy, angle1, angle2, delta; dx = dist * cos( a ); dy = dist * sin( a ); angle1 = ( ( atan2( dy, dx ) * AF_ANGLE_PI ) / 3.1415926535 ); angle2 = af_angle_atan( dx, dy ); delta = ( angle2 - angle1 ) % AF_ANGLE_2PI; if ( delta < 0 ) delta = -delta; if ( delta >= 2 ) { printf( "dist:%4d angle:%4d => (%4d,%4d) angle1:%4d angle2:%4d\n", dist, angle, dx, dy, angle1, angle2 ); } } } return 0; } #endif /* TEST */ /* END */ --- NEW FILE: afdummy.c --- /***************************************************************************/ /* */ /* afdummy.c */ /* */ /* Auto-fitter dummy routines to be used if no hinting should be */ /* performed (body). */ /* */ /* Copyright 2003, 2004, 2005 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 "afdummy.h" #include "afhints.h" static FT_Error af_dummy_hints_init( AF_GlyphHints hints, AF_ScriptMetrics metrics ) { af_glyph_hints_rescale( hints, metrics ); return 0; } static FT_Error af_dummy_hints_apply( AF_GlyphHints hints, FT_Outline* outline ) { FT_UNUSED( hints ); FT_UNUSED( outline ); return 0; } FT_CALLBACK_TABLE_DEF const AF_ScriptClassRec af_dummy_script_class = { AF_SCRIPT_NONE, NULL, sizeof( AF_ScriptMetricsRec ), (AF_Script_InitMetricsFunc) NULL, (AF_Script_ScaleMetricsFunc)NULL, (AF_Script_DoneMetricsFunc) NULL, (AF_Script_InitHintsFunc) af_dummy_hints_init, (AF_Script_ApplyHintsFunc) af_dummy_hints_apply }; /* END */ |
|
From: Ehud S. <esh...@us...> - 2006-04-21 16:22:37
|
Update of /cvsroot/roadmap/roadmap_editor/src/freetype/devel In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv22848/devel Added Files: ft2build.h ftoption.h Log Message: Import freetype sources. --- NEW FILE: ft2build.h --- /***************************************************************************/ /* */ /* ft2build.h */ /* */ /* FreeType 2 build and setup macros. */ /* (Generic version) */ /* */ /* Copyright 1996-2001, 2003 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. */ /* */ /***************************************************************************/ /* * This is a development version of <ft2build.h> that is used * to build the library in debug mode. Its only difference with * the reference is that it forces the use of the local "ftoption.h" * which contains different settings for all configuration macros. * * To use it, you must define the environment variable FT2_BUILD_INCLUDE * to point to the directory containing these two files ("ft2build.h" and * "ftoption.h"), then invoke Jam as usual. */ #ifndef __FT2_BUILD_DEVEL_H__ #define __FT2_BUILD_DEVEL_H__ #define FT_CONFIG_OPTIONS_H <ftoption.h> #include <freetype/config/ftheader.h> #endif /* __FT2_BUILD_DEVEL_H__ */ /* END */ --- NEW FILE: ftoption.h --- /***************************************************************************/ /* */ /* ftoption.h (for development) */ /* */ /* User-selectable configuration macros (specification only). */ /* */ /* Copyright 1996-2001, 2002, 2003, 2004, 2005 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. */ /* */ /***************************************************************************/ #ifndef __FTOPTION_H__ #define __FTOPTION_H__ #include <ft2build.h> FT_BEGIN_HEADER /*************************************************************************/ /* */ /* USER-SELECTABLE CONFIGURATION MACROS */ /* */ /* This file contains the default configuration macro definitions for */ /* a standard build of the FreeType library. There are three ways to */ /* use this file to build project-specific versions of the library: */ /* */ /* - You can modify this file by hand, but this is not recommended in */ /* cases where you would like to build several versions of the */ /* library from a single source directory. */ /* */ /* - You can put a copy of this file in your build directory, more */ /* precisely in "$BUILD/freetype/config/ftoption.h", where "$BUILD" */ /* is the name of a directory that is included _before_ the FreeType */ /* include path during compilation. */ /* */ /* The default FreeType Makefiles and Jamfiles use the build */ /* directory "builds/<system>" by default, but you can easily change */ /* that for your own projects. */ /* */ /* - Copy the file <ft2build.h> to "$BUILD/ft2build.h" and modify it */ /* slightly to pre-define the macro FT_CONFIG_OPTIONS_H used to */ /* locate this file during the build. For example, */ /* */ /* #define FT_CONFIG_OPTIONS_H <myftoptions.h> */ /* #include <freetype/config/ftheader.h> */ /* */ /* will use "$BUILD/myftoptions.h" instead of this file for macro */ /* definitions. */ /* */ /* Note also that you can similarly pre-define the macro */ /* FT_CONFIG_MODULES_H used to locate the file listing of the modules */ /* that are statically linked to the library at compile time. By */ /* default, this file is <freetype/config/ftmodule.h>. */ /* */ /* We highly recommend using the third method whenever possible. */ /* */ /*************************************************************************/ /*************************************************************************/ /*************************************************************************/ /**** ****/ /**** G E N E R A L F R E E T Y P E 2 C O N F I G U R A T I O N ****/ /**** ****/ /*************************************************************************/ /*************************************************************************/ /*************************************************************************/ /* */ /* Many compilers provide a non-ANSI 64-bit data type that can be used */ /* by FreeType to speed up some computations. However, this will create */ /* some problems when compiling the library in strict ANSI mode. */ /* */ /* For this reason, the use of 64-bit integers is normally disabled when */ /* the __STDC__ macro is defined. You can however disable this by */ /* defining the macro FT_CONFIG_OPTION_FORCE_INT64 here. */ /* */ /* For most compilers, this will only create compilation warnings when */ /* building the library. */ /* */ /* ObNote: The compiler-specific 64-bit integers are detected in the */ /* file "ftconfig.h" either statically or through the */ /* `configure' script on supported platforms. */ /* */ #undef FT_CONFIG_OPTION_FORCE_INT64 /*************************************************************************/ /* */ /* LZW-compressed file support. */ /* */ /* FreeType now handles font files that have been compressed with the */ /* 'compress' program. This is mostly used to parse many of the PCF */ /* files that come with various X11 distributions. The implementation */ /* uses NetBSD's `zopen' to partially uncompress the file on the fly */ /* (see src/lzw/ftgzip.c). */ /* */ /* Define this macro if you want to enable this `feature'. */ /* */ #define FT_CONFIG_OPTION_USE_LZW /*************************************************************************/ /* */ /* Gzip-compressed file support. */ /* */ /* FreeType now handles font files that have been compressed with the */ /* 'gzip' program. This is mostly used to parse many of the PCF files */ /* that come with XFree86. The implementation uses `zlib' to */ /* partially uncompress the file on the fly (see src/gzip/ftgzip.c). */ /* */ /* Define this macro if you want to enable this `feature'. See also */ /* the macro FT_CONFIG_OPTION_SYSTEM_ZLIB below. */ /* */ #define FT_CONFIG_OPTION_USE_ZLIB /*************************************************************************/ /* */ /* ZLib library selection */ /* */ /* This macro is only used when FT_CONFIG_OPTION_USE_ZLIB is defined. */ /* It allows FreeType's `ftgzip' component to link to the system's */ /* installation of the ZLib library. This is useful on systems like */ /* Unix or VMS where it generally is already available. */ /* */ /* If you let it undefined, the component will use its own copy */ /* of the zlib sources instead. These have been modified to be */ /* included directly within the component and *not* export external */ /* function names. This allows you to link any program with FreeType */ /* _and_ ZLib without linking conflicts. */ /* */ /* Do not #undef this macro here since the build system might define */ /* it for certain configurations only. */ /* */ /* #define FT_CONFIG_OPTION_SYSTEM_ZLIB */ /*************************************************************************/ /* */ /* DLL export compilation */ /* */ /* When compiling FreeType as a DLL, some systems/compilers need a */ /* special keyword in front OR after the return type of function */ /* declarations. */ /* */ /* Two macros are used within the FreeType source code to define */ /* exported library functions: FT_EXPORT and FT_EXPORT_DEF. */ /* */ /* FT_EXPORT( return_type ) */ /* */ /* is used in a function declaration, as in */ /* */ /* FT_EXPORT( FT_Error ) */ /* FT_Init_FreeType( FT_Library* alibrary ); */ /* */ /* */ /* FT_EXPORT_DEF( return_type ) */ /* */ /* is used in a function definition, as in */ /* */ /* FT_EXPORT_DEF( FT_Error ) */ /* FT_Init_FreeType( FT_Library* alibrary ) */ /* { */ /* ... some code ... */ /* return FT_Err_Ok; */ /* } */ /* */ /* You can provide your own implementation of FT_EXPORT and */ /* FT_EXPORT_DEF here if you want. If you leave them undefined, they */ /* will be later automatically defined as `extern return_type' to */ /* allow normal compilation. */ /* */ /* Do not #undef these macros here since the build system might define */ /* them for certain configurations only. */ /* */ /* #define FT_EXPORT(x) extern x */ /* #define FT_EXPORT_DEF(x) x */ /*************************************************************************/ /* */ /* Glyph Postscript Names handling */ /* */ /* By default, FreeType 2 is compiled with the `PSNames' module. This */ /* module is in charge of converting a glyph name string into a */ /* Unicode value, or return a Macintosh standard glyph name for the */ /* use with the TrueType `post' table. */ /* */ /* Undefine this macro if you do not want `PSNames' compiled in your */ /* build of FreeType. This has the following effects: */ /* */ /* - The TrueType driver will provide its own set of glyph names, */ /* if you build it to support postscript names in the TrueType */ /* `post' table. */ /* */ /* - The Type 1 driver will not be able to synthetize a Unicode */ /* charmap out of the glyphs found in the fonts. */ /* */ /* You would normally undefine this configuration macro when building */ /* a version of FreeType that doesn't contain a Type 1 or CFF driver. */ /* */ #define FT_CONFIG_OPTION_POSTSCRIPT_NAMES /*************************************************************************/ /* */ /* Postscript Names to Unicode Values support */ /* */ /* By default, FreeType 2 is built with the `PSNames' module compiled */ /* in. Among other things, the module is used to convert a glyph name */ /* into a Unicode value. This is especially useful in order to */ /* synthetize on the fly a Unicode charmap from the CFF/Type 1 driver */ /* through a big table named the `Adobe Glyph List' (AGL). */ /* */ /* Undefine this macro if you do not want the Adobe Glyph List */ /* compiled in your `PSNames' module. The Type 1 driver will not be */ /* able to synthetize a Unicode charmap out of the glyphs found in the */ /* fonts. */ /* */ #define FT_CONFIG_OPTION_ADOBE_GLYPH_LIST /*************************************************************************/ /* */ /* Support for Mac fonts */ /* */ /* Define this macro if you want support for outline fonts in Mac */ /* format (mac dfont, mac resource, macbinary containing a mac */ /* resource) on non-Mac platforms. */ /* */ /* Note that the `FOND' resource isn't checked. */ /* */ #define FT_CONFIG_OPTION_MAC_FONTS /*************************************************************************/ /* */ /* Guessing methods to access embedded resource forks */ /* */ /* Enable extra Mac fonts support on non-Mac platforms (e.g. */ /* GNU/Linux). */ /* */ /* Resource forks which include fonts data are stored sometimes in */ /* locations which users or developers don't expected. In some cases, */ /* resource forks start with some offset from the head of a file. In */ /* other cases, the actual resource fork is stored in file different */ /* from what the user specifies. If this option is activated, */ /* FreeType tries to guess whether such offsets or different file */ /* names must be used. */ /* */ /* Note that normal, direct access of resource forks is controlled via */ /* the FT_CONFIG_OPTION_MAC_FONTS option. */ /* */ #ifdef FT_CONFIG_OPTION_MAC_FONTS #define FT_CONFIG_OPTION_GUESSING_EMBEDDED_RFORK #endif /*************************************************************************/ /* */ /* Allow the use of FT_Incremental_Interface to load typefaces that */ /* contain no glyph data, but supply it via a callback function. */ /* This allows FreeType to be used with the PostScript language, using */ /* the GhostScript interpreter. */ /* */ /* #define FT_CONFIG_OPTION_INCREMENTAL */ /*************************************************************************/ /* */ /* The size in bytes of the render pool used by the scan-line converter */ /* to do all of its work. */ /* */ /* This must be greater than 4KByte. */ /* */ #define FT_RENDER_POOL_SIZE 16384L /*************************************************************************/ /* */ /* FT_MAX_MODULES */ /* */ /* The maximum number of modules that can be registered in a single */ /* FreeType library object. 32 is the default. */ /* */ #define FT_MAX_MODULES 32 /*************************************************************************/ /* */ /* Debug level */ /* */ /* FreeType can be compiled in debug or trace mode. In debug mode, */ /* errors are reported through the `ftdebug' component. In trace */ /* mode, additional messages are sent to the standard output during */ /* execution. */ /* */ /* Define FT_DEBUG_LEVEL_ERROR to build the library in debug mode. */ /* Define FT_DEBUG_LEVEL_TRACE to build it in trace mode. */ /* */ /* Don't define any of these macros to compile in `release' mode! */ /* */ /* Do not #undef these macros here since the build system might define */ /* them for certain configurations only. */ /* */ #define FT_DEBUG_LEVEL_ERROR #define FT_DEBUG_LEVEL_TRACE /*************************************************************************/ /* */ /* Memory Debugging */ /* */ /* FreeType now comes with an integrated memory debugger that is */ /* capable of detecting simple errors like memory leaks or double */ /* deletes. To compile it within your build of the library, you */ /* should define FT_DEBUG_MEMORY here. */ /* */ /* Note that the memory debugger is only activated at runtime when */ /* when the _environment_ variable "FT2_DEBUG_MEMORY" is defined also! */ /* */ /* Do not #undef this macro here since the build system might define */ /* it for certain configurations only. */ /* */ #define FT_DEBUG_MEMORY /*************************************************************************/ /* */ /* Module errors */ /* */ /* If this macro is set (which is _not_ the default), the higher byte */ /* of an error code gives the module in which the error has occurred, */ /* while the lower byte is the real error code. */ /* */ /* Setting this macro makes sense for debugging purposes only, since */ /* it would break source compatibility of certain programs that use */ /* FreeType 2. */ /* */ /* More details can be found in the files ftmoderr.h and fterrors.h. */ /* */ #undef FT_CONFIG_OPTION_USE_MODULE_ERRORS /*************************************************************************/ /*************************************************************************/ /**** ****/ /**** S F N T D R I V E R C O N F I G U R A T I O N ****/ /**** ****/ /*************************************************************************/ /*************************************************************************/ /*************************************************************************/ /* */ /* Define TT_CONFIG_OPTION_EMBEDDED_BITMAPS if you want to support */ /* embedded bitmaps in all formats using the SFNT module (namely */ /* TrueType & OpenType). */ /* */ #define TT_CONFIG_OPTION_EMBEDDED_BITMAPS /*************************************************************************/ /* */ /* Define TT_CONFIG_OPTION_POSTSCRIPT_NAMES if you want to be able to */ /* load and enumerate the glyph Postscript names in a TrueType or */ /* OpenType file. */ /* */ /* Note that when you do not compile the `PSNames' module by undefining */ /* the above FT_CONFIG_OPTION_POSTSCRIPT_NAMES, the `sfnt' module will */ /* contain additional code used to read the PS Names table from a font. */ /* */ /* (By default, the module uses `PSNames' to extract glyph names.) */ /* */ #define TT_CONFIG_OPTION_POSTSCRIPT_NAMES /*************************************************************************/ /* */ /* Define TT_CONFIG_OPTION_SFNT_NAMES if your applications need to */ /* access the internal name table in a SFNT-based format like TrueType */ /* or OpenType. The name table contains various strings used to */ /* describe the font, like family name, copyright, version, etc. It */ /* does not contain any glyph name though. */ /* */ /* Accessing SFNT names is done through the functions declared in */ /* `freetype/ftnames.h'. */ /* */ #define TT_CONFIG_OPTION_SFNT_NAMES /*************************************************************************/ /* */ /* TrueType CMap support */ /* */ /* Here you can fine-tune which TrueType CMap table format shall be */ /* supported. */ #define TT_CONFIG_CMAP_FORMAT_0 #define TT_CONFIG_CMAP_FORMAT_2 #define TT_CONFIG_CMAP_FORMAT_4 #define TT_CONFIG_CMAP_FORMAT_6 #define TT_CONFIG_CMAP_FORMAT_8 #define TT_CONFIG_CMAP_FORMAT_10 #define TT_CONFIG_CMAP_FORMAT_12 /*************************************************************************/ /*************************************************************************/ /**** ****/ /**** T R U E T Y P E D R I V E R C O N F I G U R A T I O N ****/ /**** ****/ /*************************************************************************/ /*************************************************************************/ /*************************************************************************/ /* */ /* Define TT_CONFIG_OPTION_BYTECODE_INTERPRETER if you want to compile */ /* a bytecode interpreter in the TrueType driver. Note that there are */ /* important patent issues related to the use of the interpreter. */ /* */ /* By undefining this, you will only compile the code necessary to load */ /* TrueType glyphs without hinting. */ /* */ /* Do not #undef this macro here, since the build system might */ /* define it for certain configurations only. */ /* */ #define TT_CONFIG_OPTION_BYTECODE_INTERPRETER /*************************************************************************/ /* */ /* Define TT_CONFIG_OPTION_UNPATENTED_HINTING (in addition to */ /* TT_CONFIG_OPTION_BYTECODE_INTERPRETER) to compile the unpatented */ /* work-around hinting system. Note that for the moment, the algorithm */ /* is only used when selected at runtime through the parameter tag */ /* FT_PARAM_TAG_UNPATENTED_HINTING; or when the debug hook */ /* FT_DEBUG_HOOK_UNPATENTED_HINTING is globally activated. */ /* */ /* #define TT_CONFIG_OPTION_UNPATENTED_HINTING */ /*************************************************************************/ /* */ /* Define TT_CONFIG_OPTION_INTERPRETER_SWITCH to compile the TrueType */ /* bytecode interpreter with a huge switch statement, rather than a call */ /* table. This results in smaller and faster code for a number of */ /* architectures. */ /* */ /* Note however that on some compiler/processor combinations, undefining */ /* this macro will generate faster, though larger, code. */ /* */ #define TT_CONFIG_OPTION_INTERPRETER_SWITCH /*************************************************************************/ /* */ /* Define TT_CONFIG_OPTION_COMPONENT_OFFSET_SCALED to compile the */ /* TrueType glyph loader to use Apple's definition of how to handle */ /* component offsets in composite glyphs. */ /* */ /* Apple and MS disagree on the default behavior of component offsets */ /* in composites. Apple says that they should be scaled by the scale */ /* factors in the transformation matrix (roughly, it's more complex) */ /* while MS says they should not. OpenType defines two bits in the */ /* composite flags array which can be used to disambiguate, but old */ /* fonts will not have them. */ /* */ /* http://partners.adobe.com/asn/developer/opentype/glyf.html */ /* http://fonts.apple.com/TTRefMan/RM06/Chap6glyf.html */ /* */ #undef TT_CONFIG_OPTION_COMPONENT_OFFSET_SCALED /*************************************************************************/ /* */ /* Define TT_CONFIG_OPTION_GX_VAR_SUPPORT if you want to include */ /* support for Apple's distortable font technology (fvar, gvar, cvar, */ /* and avar tables). This has many similarities to Type 1 Multiple */ /* Masters support. */ /* */ #define TT_CONFIG_OPTION_GX_VAR_SUPPORT /*************************************************************************/ /*************************************************************************/ /**** ****/ /**** T Y P E 1 D R I V E R C O N F I G U R A T I O N ****/ /**** ****/ /*************************************************************************/ /*************************************************************************/ /*************************************************************************/ /* */ /* T1_MAX_DICT_DEPTH is the maximal depth of nest dictionaries and */ /* arrays in the Type 1 stream (see t1load.c). A minimum of 4 is */ /* required. */ /* */ #define T1_MAX_DICT_DEPTH 5 /*************************************************************************/ /* */ /* T1_MAX_SUBRS_CALLS details the maximum number of nested sub-routine */ /* calls during glyph loading. */ /* */ #define T1_MAX_SUBRS_CALLS 16 /*************************************************************************/ /* */ /* T1_MAX_CHARSTRING_OPERANDS is the charstring stack's capacity. A */ /* minimum of 16 is required. */ /* */ /* The Chinese font MingTiEG-Medium (CNS 11643 character set) needs 256. */ /* */ #define T1_MAX_CHARSTRINGS_OPERANDS 256 /*************************************************************************/ /* */ /* Define this configuration macro if you want to prevent the */ /* compilation of `t1afm', which is in charge of reading Type 1 AFM */ /* files into an existing face. Note that if set, the T1 driver will be */ /* unable to produce kerning distances. */ /* */ #undef T1_CONFIG_OPTION_NO_AFM /*************************************************************************/ /* */ /* Define this configuration macro if you want to prevent the */ /* compilation of the Multiple Masters font support in the Type 1 */ /* driver. */ /* */ #undef T1_CONFIG_OPTION_NO_MM_SUPPORT /* */ /* * This temporary macro is used to control various optimizations for * reducing the heap footprint of memory-mapped TrueType files. * */ /* #define FT_OPTIMIZE_MEMORY */ FT_END_HEADER #endif /* __FTOPTION_H__ */ /* END */ |
Update of /cvsroot/roadmap/roadmap_editor/src/freetype/include/freetype In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv22848/include/freetype Added Files: freetype.h ftbbox.h ftbdf.h ftbitmap.h ftcache.h ftchapters.h fterrdef.h fterrors.h ftglyph.h ftgzip.h ftimage.h ftincrem.h ftlist.h ftlzw.h ftmac.h ftmm.h ftmodapi.h ftmoderr.h ftotval.h ftoutln.h ftpfr.h ftrender.h ftsizes.h ftsnames.h ftstroke.h ftsynth.h ftsysio.h ftsysmem.h ftsystem.h fttrigon.h fttypes.h ftwinfnt.h ftxf86.h t1tables.h ttnameid.h tttables.h tttags.h ttunpat.h Log Message: Import freetype sources. --- NEW FILE: ftincrem.h --- /***************************************************************************/ /* */ /* ftincrem.h */ /* */ /* FreeType incremental loading (specification). */ /* */ /* Copyright 2002, 2003 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. */ /* */ /***************************************************************************/ #ifndef __FTINCREM_H__ #define __FTINCREM_H__ #include <ft2build.h> #include FT_FREETYPE_H #ifdef FREETYPE_H #error "freetype.h of FreeType 1 has been loaded!" #error "Please fix the directory search order for header files" #error "so that freetype.h of FreeType 2 is found first." #endif FT_BEGIN_HEADER /*************************************************************************** * * @type: * FT_Incremental * * @description: * An opaque type describing a user-provided object used to implement * "incremental" glyph loading within FreeType. This is used to support * embedded fonts in certain environments (e.g. Postscript interpreters), * where the glyph data isn't in the font file, or must be overridden by * different values. * * @note: * It is up to client applications to create and implement @FT_Incremental * objects, as long as they provide implementations for the methods * @FT_Incremental_GetGlyphDataFunc, @FT_Incremental_FreeGlyphDataFunc * and @FT_Incremental_GetGlyphMetricsFunc. * * See the description of @FT_Incremental_InterfaceRec to understand how * to use incremental objects with FreeType. */ typedef struct FT_IncrementalRec_* FT_Incremental; /*************************************************************************** * * @struct: * FT_Incremental_Metrics * * @description: * A small structure used to contain the basic glyph metrics returned * by the @FT_Incremental_GetGlyphMetricsFunc method. * * @fields: * bearing_x :: * Left bearing, in font units. * * bearing_y :: * Top bearing, in font units. * * advance :: * Glyph advance, in font units. * * @note: * These correspond to horizontal or vertical metrics depending on the * value of the 'vertical' argument to the function * @FT_Incremental_GetGlyphMetricsFunc. */ typedef struct FT_Incremental_MetricsRec_ { FT_Long bearing_x; FT_Long bearing_y; FT_Long advance; } FT_Incremental_MetricsRec, *FT_Incremental_Metrics; /*************************************************************************** * * @type: * FT_Incremental_GetGlyphDataFunc * * @description: * A function called by FreeType to access a given glyph's data bytes * during @FT_Load_Glyph or @FT_Load_Char if incremental loading is * enabled. * * Note that the format of the glyph's data bytes depends on the font * file format. For TrueType, it must correspond to the raw bytes within * the 'glyf' table. For Postscript formats, it must correspond to the * *unencrypted* charstring bytes, without any 'lenIV' header. It is * undefined for any other format. * * @input: * incremental :: * Handle to an opaque @FT_Incremental handle provided by the client * application. * * glyph_index :: * Index of relevant glyph. * * @output: * adata :: * A structure describing the returned glyph data bytes (which will be * accessed as a read-only byte block). * * @return: * FreeType error code. 0 means success. * * @note: * If this function returns succesfully the method * @FT_Incremental_FreeGlyphDataFunc will be called later to release * the data bytes. * * Nested calls to @FT_Incremental_GetGlyphDataFunc can happen for * compound glyphs. */ typedef FT_Error (*FT_Incremental_GetGlyphDataFunc)( FT_Incremental incremental, FT_UInt glyph_index, FT_Data* adata ); /*************************************************************************** * * @type: * FT_Incremental_FreeGlyphDataFunc * * @description: * A function used to release the glyph data bytes returned by a * successful call to @FT_Incremental_GetGlyphDataFunc. * * @input: * incremental :: * A handle to an opaque @FT_Incremental handle provided by the client * application. * * data :: * A structure describing the glyph data bytes (which will be accessed * as a read-only byte block). */ typedef void (*FT_Incremental_FreeGlyphDataFunc)( FT_Incremental incremental, FT_Data* data ); /*************************************************************************** * * @type: * FT_Incremental_GetGlyphMetricsFunc * * @description: * A function used to retrieve the basic metrics of a given glyph index * before accessing its data. This is necessary because, in certain * formats like TrueType, the metrics are stored in a different place from * the glyph images proper. * * @input: * incremental :: * A handle to an opaque @FT_Incremental handle provided by the client * application. * * glyph_index :: * Index of relevant glyph. * * vertical :: * If true, return vertical metrics. * * ametrics :: * This parameter is used for both input and output. * The original glyph metrics, if any, in font units. If metrics are * not available all the values must be set to zero. * * @output: * ametrics :: * The replacement glyph metrics in font units. * */ typedef FT_Error (*FT_Incremental_GetGlyphMetricsFunc) ( FT_Incremental incremental, FT_UInt glyph_index, FT_Bool vertical, FT_Incremental_MetricsRec *ametrics ); /************************************************************************** * * @struct: * FT_Incremental_FuncsRec * * @description: * A table of functions for accessing fonts that load data * incrementally. Used in @FT_Incremental_InterfaceRec. * * @fields: * get_glyph_data :: * The function to get glyph data. Must not be null. * * free_glyph_data :: * The function to release glyph data. Must not be null. * * get_glyph_metrics :: * The function to get glyph metrics. May be null if the font does * not provide overriding glyph metrics. */ typedef struct FT_Incremental_FuncsRec_ { FT_Incremental_GetGlyphDataFunc get_glyph_data; FT_Incremental_FreeGlyphDataFunc free_glyph_data; FT_Incremental_GetGlyphMetricsFunc get_glyph_metrics; } FT_Incremental_FuncsRec; /*************************************************************************** * * @struct: * FT_Incremental_InterfaceRec * * @description: * A structure to be used with @FT_Open_Face to indicate that the user * wants to support incremental glyph loading. You should use it with * @FT_PARAM_TAG_INCREMENTAL as in the following example: * * { * FT_Incremental_InterfaceRec inc_int; * FT_Parameter parameter; * FT_Open_Args open_args; * * * // set up incremental descriptor * inc_int.funcs = my_funcs; * inc_int.object = my_object; * * // set up optional parameter * parameter.tag = FT_PARAM_TAG_INCREMENTAL; * parameter.data = &inc_int; * * // set up FT_Open_Args structure * open_args.flags = FT_OPEN_PATHNAME | FT_OPEN_PARAMS; * open_args.pathname = my_font_pathname; * open_args.num_params = 1; * open_args.params = ¶meter; // we use one optional argument * * // open the font * error = FT_Open_Face( library, &open_args, index, &face ); * ... * } */ typedef struct FT_Incremental_InterfaceRec_ { const FT_Incremental_FuncsRec* funcs; FT_Incremental object; } FT_Incremental_InterfaceRec; /*************************************************************************** * * @constant: * FT_PARAM_TAG_INCREMENTAL * * @description: * A constant used as the tag of @FT_Parameter structures to indicate * an incremental loading object to be used by FreeType. * */ #define FT_PARAM_TAG_INCREMENTAL FT_MAKE_TAG( 'i', 'n', 'c', 'r' ) /* */ FT_END_HEADER #endif /* __FTINCREM_H__ */ /* END */ --- NEW FILE: fterrors.h --- /***************************************************************************/ /* */ /* fterrors.h */ /* */ /* FreeType error code handling (specification). */ /* */ /* Copyright 1996-2001, 2002, 2004 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. */ /* */ /***************************************************************************/ /*************************************************************************/ /* */ /* This special header file is used to define the handling of FT2 */ /* enumeration constants. It can also be used to generate error message */ /* strings with a small macro trick explained below. */ /* */ /* I - Error Formats */ /* ----------------- */ /* */ /* The configuration macro FT_CONFIG_OPTION_USE_MODULE_ERRORS can be */ /* defined in ftoption.h in order to make the higher byte indicate */ /* the module where the error has happened (this is not compatible */ /* with standard builds of FreeType 2). You can then use the macro */ /* FT_ERROR_BASE macro to extract the generic error code from an */ /* FT_Error value. */ /* */ /* */ /* II - Error Message strings */ /* -------------------------- */ /* */ /* The error definitions below are made through special macros that */ /* allow client applications to build a table of error message strings */ /* if they need it. The strings are not included in a normal build of */ /* FreeType 2 to save space (most client applications do not use */ /* them). */ /* */ /* To do so, you have to define the following macros before including */ /* this file: */ /* */ /* FT_ERROR_START_LIST :: */ /* This macro is called before anything else to define the start of */ /* the error list. It is followed by several FT_ERROR_DEF calls */ /* (see below). */ /* */ /* FT_ERROR_DEF( e, v, s ) :: */ /* This macro is called to define one single error. */ /* `e' is the error code identifier (e.g. FT_Err_Invalid_Argument). */ /* `v' is the error numerical value. */ /* `s' is the corresponding error string. */ /* */ /* FT_ERROR_END_LIST :: */ /* This macro ends the list. */ /* */ /* Additionally, you have to undefine __FTERRORS_H__ before #including */ /* this file. */ /* */ /* Here is a simple example: */ /* */ /* { */ /* #undef __FTERRORS_H__ */ /* #define FT_ERRORDEF( e, v, s ) { e, s }, */ /* #define FT_ERROR_START_LIST { */ /* #define FT_ERROR_END_LIST { 0, 0 } }; */ /* */ /* const struct */ /* { */ /* int err_code; */ /* const char* err_msg */ /* } ft_errors[] = */ /* */ /* #include FT_ERRORS_H */ /* } */ /* */ /*************************************************************************/ #ifndef __FTERRORS_H__ #define __FTERRORS_H__ /* include module base error codes */ #include FT_MODULE_ERRORS_H /*******************************************************************/ /*******************************************************************/ /***** *****/ /***** SETUP MACROS *****/ /***** *****/ /*******************************************************************/ /*******************************************************************/ #undef FT_NEED_EXTERN_C #undef FT_ERR_XCAT #undef FT_ERR_CAT #define FT_ERR_XCAT( x, y ) x ## y #define FT_ERR_CAT( x, y ) FT_ERR_XCAT( x, y ) /* FT_ERR_PREFIX is used as a prefix for error identifiers. */ /* By default, we use `FT_Err_'. */ /* */ #ifndef FT_ERR_PREFIX #define FT_ERR_PREFIX FT_Err_ #endif /* FT_ERR_BASE is used as the base for module-specific errors. */ /* */ #ifdef FT_CONFIG_OPTION_USE_MODULE_ERRORS #ifndef FT_ERR_BASE #define FT_ERR_BASE FT_Mod_Err_Base #endif #else #undef FT_ERR_BASE #define FT_ERR_BASE 0 #endif /* FT_CONFIG_OPTION_USE_MODULE_ERRORS */ /* If FT_ERRORDEF is not defined, we need to define a simple */ /* enumeration type. */ /* */ #ifndef FT_ERRORDEF #define FT_ERRORDEF( e, v, s ) e = v, #define FT_ERROR_START_LIST enum { #define FT_ERROR_END_LIST FT_ERR_CAT( FT_ERR_PREFIX, Max ) }; #ifdef __cplusplus #define FT_NEED_EXTERN_C extern "C" { #endif #endif /* !FT_ERRORDEF */ /* this macro is used to define an error */ #define FT_ERRORDEF_( e, v, s ) \ FT_ERRORDEF( FT_ERR_CAT( FT_ERR_PREFIX, e ), v + FT_ERR_BASE, s ) /* this is only used for <module>_Err_Ok, which must be 0! */ #define FT_NOERRORDEF_( e, v, s ) \ FT_ERRORDEF( FT_ERR_CAT( FT_ERR_PREFIX, e ), v, s ) #ifdef FT_ERROR_START_LIST FT_ERROR_START_LIST #endif /* now include the error codes */ #include FT_ERROR_DEFINITIONS_H #ifdef FT_ERROR_END_LIST FT_ERROR_END_LIST #endif /*******************************************************************/ /*******************************************************************/ /***** *****/ /***** SIMPLE CLEANUP *****/ /***** *****/ /*******************************************************************/ /*******************************************************************/ #ifdef FT_NEED_EXTERN_C } #endif #undef FT_ERROR_START_LIST #undef FT_ERROR_END_LIST #undef FT_ERRORDEF #undef FT_ERRORDEF_ #undef FT_NOERRORDEF_ #undef FT_NEED_EXTERN_C #undef FT_ERR_CONCAT #undef FT_ERR_BASE /* FT_KEEP_ERR_PREFIX is needed for ftvalid.h */ #ifndef FT_KEEP_ERR_PREFIX #undef FT_ERR_PREFIX #endif #endif /* __FTERRORS_H__ */ /* END */ --- NEW FILE: ftmodapi.h --- /***************************************************************************/ /* */ /* ftmodapi.h */ /* */ /* FreeType modules public interface (specification). */ /* */ /* Copyright 1996-2001, 2002, 2003 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. */ /* */ /***************************************************************************/ #ifndef __FTMODAPI_H__ #define __FTMODAPI_H__ #include <ft2build.h> #include FT_FREETYPE_H #ifdef FREETYPE_H #error "freetype.h of FreeType 1 has been loaded!" #error "Please fix the directory search order for header files" #error "so that freetype.h of FreeType 2 is found first." #endif FT_BEGIN_HEADER /*************************************************************************/ /* */ /* <Section> */ /* module_management */ /* */ /* <Title> */ /* Module Management */ /* */ /* <Abstract> */ /* How to add, upgrade, and remove modules from FreeType. */ /* */ /* <Description> */ /* The definitions below are used to manage modules within FreeType. */ /* Modules can be added, upgraded, and removed at runtime. */ /* */ /*************************************************************************/ /* module bit flags */ #define FT_MODULE_FONT_DRIVER 1 /* this module is a font driver */ #define FT_MODULE_RENDERER 2 /* this module is a renderer */ #define FT_MODULE_HINTER 4 /* this module is a glyph hinter */ #define FT_MODULE_STYLER 8 /* this module is a styler */ #define FT_MODULE_DRIVER_SCALABLE 0x100 /* the driver supports */ /* scalable fonts */ #define FT_MODULE_DRIVER_NO_OUTLINES 0x200 /* the driver does not */ /* support vector outlines */ #define FT_MODULE_DRIVER_HAS_HINTER 0x400 /* the driver provides its */ /* own hinter */ /* deprecated values */ #define ft_module_font_driver FT_MODULE_FONT_DRIVER #define ft_module_renderer FT_MODULE_RENDERER #define ft_module_hinter FT_MODULE_HINTER #define ft_module_styler FT_MODULE_STYLER #define ft_module_driver_scalable FT_MODULE_DRIVER_SCALABLE #define ft_module_driver_no_outlines FT_MODULE_DRIVER_NO_OUTLINES #define ft_module_driver_has_hinter FT_MODULE_DRIVER_HAS_HINTER typedef FT_Pointer FT_Module_Interface; typedef FT_Error (*FT_Module_Constructor)( FT_Module module ); typedef void (*FT_Module_Destructor)( FT_Module module ); typedef FT_Module_Interface (*FT_Module_Requester)( FT_Module module, const char* name ); /*************************************************************************/ /* */ /* <Struct> */ /* FT_Module_Class */ /* */ /* <Description> */ /* The module class descriptor. */ /* */ /* <Fields> */ /* module_flags :: Bit flags describing the module. */ /* */ /* module_size :: The size of one module object/instance in */ /* bytes. */ /* */ /* module_name :: The name of the module. */ /* */ /* module_version :: The version, as a 16.16 fixed number */ /* (major.minor). */ /* */ /* module_requires :: The version of FreeType this module requires */ /* (starts at version 2.0, i.e 0x20000) */ /* */ /* module_init :: A function used to initialize (not create) a */ /* new module object. */ /* */ /* module_done :: A function used to finalize (not destroy) a */ /* given module object */ /* */ /* get_interface :: Queries a given module for a specific */ /* interface by name. */ /* */ typedef struct FT_Module_Class_ { FT_ULong module_flags; FT_Long module_size; const FT_String* module_name; FT_Fixed module_version; FT_Fixed module_requires; const void* module_interface; FT_Module_Constructor module_init; FT_Module_Destructor module_done; FT_Module_Requester get_interface; } FT_Module_Class; /*************************************************************************/ /* */ /* <Function> */ /* FT_Add_Module */ /* */ /* <Description> */ /* Adds a new module to a given library instance. */ /* */ /* <InOut> */ /* library :: A handle to the library object. */ /* */ /* <Input> */ /* clazz :: A pointer to class descriptor for the module. */ /* */ /* <Return> */ /* FreeType error code. 0 means success. */ /* */ /* <Note> */ /* An error will be returned if a module already exists by that name, */ /* or if the module requires a version of FreeType that is too great. */ /* */ FT_EXPORT( FT_Error ) FT_Add_Module( FT_Library library, const FT_Module_Class* clazz ); /*************************************************************************/ /* */ /* <Function> */ /* FT_Get_Module */ /* */ /* <Description> */ /* Finds a module by its name. */ /* */ /* <Input> */ /* library :: A handle to the library object. */ /* */ /* module_name :: The module's name (as an ASCII string). */ /* */ /* <Return> */ /* A module handle. 0 if none was found. */ /* */ /* <Note> */ /* You should better be familiar with FreeType internals to know */ /* which module to look for :-) */ /* */ FT_EXPORT( FT_Module ) FT_Get_Module( FT_Library library, const char* module_name ); /*************************************************************************/ /* */ /* <Function> */ /* FT_Remove_Module */ /* */ /* <Description> */ /* Removes a given module from a library instance. */ /* */ /* <InOut> */ /* library :: A handle to a library object. */ /* */ /* <Input> */ /* module :: A handle to a module object. */ /* */ /* <Return> */ /* FreeType error code. 0 means success. */ /* */ /* <Note> */ /* The module object is destroyed by the function in case of success. */ /* */ FT_EXPORT( FT_Error ) FT_Remove_Module( FT_Library library, FT_Module module ); /*************************************************************************/ /* */ /* <Function> */ /* FT_New_Library */ /* */ /* <Description> */ /* This function is used to create a new FreeType library instance */ /* from a given memory object. It is thus possible to use libraries */ /* with distinct memory allocators within the same program. */ /* */ /* <Input> */ /* memory :: A handle to the original memory object. */ /* */ /* <Output> */ /* alibrary :: A pointer to handle of a new library object. */ /* */ /* <Return> */ /* FreeType error code. 0 means success. */ /* */ FT_EXPORT( FT_Error ) FT_New_Library( FT_Memory memory, FT_Library *alibrary ); /*************************************************************************/ /* */ /* <Function> */ /* FT_Done_Library */ /* */ /* <Description> */ /* Discards a given library object. This closes all drivers and */ /* discards all resource objects. */ /* */ /* <Input> */ /* library :: A handle to the target library. */ /* */ /* <Return> */ /* FreeType error code. 0 means success. */ /* */ FT_EXPORT( FT_Error ) FT_Done_Library( FT_Library library ); typedef void (*FT_DebugHook_Func)( void* arg ); /*************************************************************************/ /* */ /* <Function> */ /* FT_Set_Debug_Hook */ /* */ /* <Description> */ /* Sets a debug hook function for debugging the interpreter of a font */ /* format. */ /* */ /* <InOut> */ /* library :: A handle to the library object. */ /* */ /* <Input> */ /* hook_index :: The index of the debug hook. You should use the */ /* values defined in ftobjs.h, e.g. */ /* FT_DEBUG_HOOK_TRUETYPE. */ /* */ /* debug_hook :: The function used to debug the interpreter. */ /* */ /* <Note> */ /* Currently, four debug hook slots are available, but only two (for */ /* the TrueType and the Type 1 interpreter) are defined. */ /* */ FT_EXPORT( void ) FT_Set_Debug_Hook( FT_Library library, FT_UInt hook_index, FT_DebugHook_Func debug_hook ); /*************************************************************************/ /* */ /* <Function> */ /* FT_Add_Default_Modules */ /* */ /* <Description> */ /* Adds the set of default drivers to a given library object. */ /* This is only useful when you create a library object with */ /* FT_New_Library() (usually to plug a custom memory manager). */ /* */ /* <InOut> */ /* library :: A handle to a new library object. */ /* */ FT_EXPORT( void ) FT_Add_Default_Modules( FT_Library library ); /* */ FT_END_HEADER #endif /* __FTMODAPI_H__ */ /* END */ --- NEW FILE: ftpfr.h --- /***************************************************************************/ /* */ /* ftpfr.h */ /* */ /* FreeType API for accessing PFR-specific data (specification only). */ /* */ /* Copyright 2002, 2003, 2004 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. */ /* */ /***************************************************************************/ #ifndef __FTPFR_H__ #define __FTPFR_H__ #include <ft2build.h> #include FT_FREETYPE_H #ifdef FREETYPE_H #error "freetype.h of FreeType 1 has been loaded!" #error "Please fix the directory search order for header files" #error "so that freetype.h of FreeType 2 is found first." #endif FT_BEGIN_HEADER /*************************************************************************/ /* */ /* <Section> */ /* pfr_fonts */ /* */ /* <Title> */ /* PFR Fonts */ /* */ /* <Abstract> */ /* PFR/TrueDoc specific API. */ /* */ /* <Description> */ /* This section contains the declaration of PFR-specific functions. */ /* */ /*************************************************************************/ /********************************************************************** * * @function: * FT_Get_PFR_Metrics * * @description: * Return the outline and metrics resolutions of a given PFR face. * * @input: * face :: Handle to the input face. It can be a non-PFR face. * * @output: * aoutline_resolution :: * Outline resolution. This is equivalent to `face->units_per_EM'. * Optional (parameter can be NULL). * * ametrics_resolution :: * Metrics resolution. This is equivalent to `outline_resolution' * for non-PFR fonts. Optional (parameter can be NULL). * * ametrics_x_scale :: * A 16.16 fixed-point number used to scale distance expressed * in metrics units to device sub-pixels. This is equivalent to * `face->size->x_scale', but for metrics only. Optional (parameter * can be NULL) * * ametrics_y_scale :: * Same as `ametrics_x_scale' but for the vertical direction. * optional (parameter can be NULL) * * @return: * FreeType error code. 0 means success. * * @note: * If the input face is not a PFR, this function will return an error. * However, in all cases, it will return valid values. */ FT_EXPORT( FT_Error ) FT_Get_PFR_Metrics( FT_Face face, FT_UInt *aoutline_resolution, FT_UInt *ametrics_resolution, FT_Fixed *ametrics_x_scale, FT_Fixed *ametrics_y_scale ); /********************************************************************** * * @function: * FT_Get_PFR_Kerning * * @description: * Return the kerning pair corresponding to two glyphs in a PFR face. * The distance is expressed in metrics units, unlike the result of * @FT_Get_Kerning. * * @input: * face :: A handle to the input face. * * left :: Index of the left glyph. * * right :: Index of the right glyph. * * @output: * avector :: A kerning vector. * * @return: * FreeType error code. 0 means success. * * @note: * This function always return distances in original PFR metrics * units. This is unlike @FT_Get_Kerning with the @FT_KERNING_UNSCALED * mode, which always returns distances converted to outline units. * * You can use the value of the `x_scale' and `y_scale' parameters * returned by @FT_Get_PFR_Metrics to scale these to device sub-pixels. */ FT_EXPORT( FT_Error ) FT_Get_PFR_Kerning( FT_Face face, FT_UInt left, FT_UInt right, FT_Vector *avector ); /********************************************************************** * * @function: * FT_Get_PFR_Advance * * @description: * Return a given glyph advance, expressed in original metrics units, * from a PFR font. * * @input: * face :: A handle to the input face. * * gindex :: The glyph index. * * @output: * aadvance :: The glyph advance in metrics units. * * @return: * FreeType error code. 0 means success. * * @note: * You can use the `x_scale' or `y_scale' results of @FT_Get_PFR_Metrics * to convert the advance to device sub-pixels (i.e. 1/64th of pixels). */ FT_EXPORT( FT_Error ) FT_Get_PFR_Advance( FT_Face face, FT_UInt gindex, FT_Pos *aadvance ); /* */ FT_END_HEADER #endif /* __FTPFR_H__ */ /* END */ --- NEW FILE: ttunpat.h --- /***************************************************************************/ /* */ /* ttunpat.h */ /* */ /* Definitions for the unpatented TrueType hinting system */ /* */ /* Copyright 2003 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* Written by Graham Asher <gra...@bt...> */ /* */ /* 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. */ /* */ /***************************************************************************/ #ifndef __TTUNPAT_H__ #define __TTUNPAT_H__ #include <ft2build.h> #include FT_FREETYPE_H #ifdef FREETYPE_H #error "freetype.h of FreeType 1 has been loaded!" #error "Please fix the directory search order for header files" #error "so that freetype.h of FreeType 2 is found first." #endif FT_BEGIN_HEADER /*************************************************************************** * * @constant: * FT_PARAM_TAG_UNPATENTED_HINTING * * @description: * A constant used as the tag of an @FT_Parameter structure to indicate * that unpatented methods only should be used by the TrueType bytecode * interpreter for a typeface opened by FT_Open_Face. * */ #define FT_PARAM_TAG_UNPATENTED_HINTING FT_MAKE_TAG( 'u', 'n', 'p', 'a' ) /* */ FT_END_HEADER #endif /* __TTUNPAT_H__ */ /* END */ --- NEW FILE: tttags.h --- /***************************************************************************/ /* */ /* tttags.h */ /* */ /* Tags for TrueType and OpenType tables (specification only). */ /* */ /* Copyright 1996-2001, 2004 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. */ /* */ /***************************************************************************/ #ifndef __TTAGS_H__ #define __TTAGS_H__ #include <ft2build.h> #include FT_FREETYPE_H #ifdef FREETYPE_H #error "freetype.h of FreeType 1 has been loaded!" #error "Please fix the directory search order for header files" #error "so that freetype.h of FreeType 2 is found first." #endif FT_BEGIN_HEADER #define TTAG_avar FT_MAKE_TAG( 'a', 'v', 'a', 'r' ) #define TTAG_BASE FT_MAKE_TAG( 'B', 'A', 'S', 'E' ) #define TTAG_bdat FT_MAKE_TAG( 'b', 'd', 'a', 't' ) #define TTAG_bhed FT_MAKE_TAG( 'b', 'h', 'e', 'd' ) #define TTAG_bloc FT_MAKE_TAG( 'b', 'l', 'o', 'c' ) #define TTAG_CFF FT_MAKE_TAG( 'C', 'F', 'F', ' ' ) #define TTAG_cmap FT_MAKE_TAG( 'c', 'm', 'a', 'p' ) #define TTAG_cvar FT_MAKE_TAG( 'c', 'v', 'a', 'r' ) #define TTAG_cvt FT_MAKE_TAG( 'c', 'v', 't', ' ' ) #define TTAG_DSIG FT_MAKE_TAG( 'D', 'S', 'I', 'G' ) #define TTAG_EBDT FT_MAKE_TAG( 'E', 'B', 'D', 'T' ) #define TTAG_EBLC FT_MAKE_TAG( 'E', 'B', 'L', 'C' ) #define TTAG_EBSC FT_MAKE_TAG( 'E', 'B', 'S', 'C' ) #define TTAG_fpgm FT_MAKE_TAG( 'f', 'p', 'g', 'm' ) #define TTAG_fvar FT_MAKE_TAG( 'f', 'v', 'a', 'r' ) #define TTAG_gasp FT_MAKE_TAG( 'g', 'a', 's', 'p' ) #define TTAG_GDEF FT_MAKE_TAG( 'G', 'D', 'E', 'F' ) #define TTAG_glyf FT_MAKE_TAG( 'g', 'l', 'y', 'f' ) #define TTAG_GPOS FT_MAKE_TAG( 'G', 'P', 'O', 'S' ) #define TTAG_GSUB FT_MAKE_TAG( 'G', 'S', 'U', 'B' ) #define TTAG_gvar FT_MAKE_TAG( 'g', 'v', 'a', 'r' ) #define TTAG_hdmx FT_MAKE_TAG( 'h', 'd', 'm', 'x' ) #define TTAG_head FT_MAKE_TAG( 'h', 'e', 'a', 'd' ) #define TTAG_hhea FT_MAKE_TAG( 'h', 'h', 'e', 'a' ) #define TTAG_hmtx FT_MAKE_TAG( 'h', 'm', 't', 'x' ) #define TTAG_JSTF FT_MAKE_TAG( 'J', 'S', 'T', 'F' ) #define TTAG_kern FT_MAKE_TAG( 'k', 'e', 'r', 'n' ) #define TTAG_loca FT_MAKE_TAG( 'l', 'o', 'c', 'a' ) #define TTAG_LTSH FT_MAKE_TAG( 'L', 'T', 'S', 'H' ) #define TTAG_maxp FT_MAKE_TAG( 'm', 'a', 'x', 'p' ) #define TTAG_MMFX FT_MAKE_TAG( 'M', 'M', 'F', 'X' ) #define TTAG_MMSD FT_MAKE_TAG( 'M', 'M', 'S', 'D' ) #define TTAG_name FT_MAKE_TAG( 'n', 'a', 'm', 'e' ) #define TTAG_OS2 FT_MAKE_TAG( 'O', 'S', '/', '2' ) #define TTAG_OTTO FT_MAKE_TAG( 'O', 'T', 'T', 'O' ) #define TTAG_PCLT FT_MAKE_TAG( 'P', 'C', 'L', 'T' ) #define TTAG_post FT_MAKE_TAG( 'p', 'o', 's', 't' ) #define TTAG_prep FT_MAKE_TAG( 'p', 'r', 'e', 'p' ) #define TTAG_true FT_MAKE_TAG( 't', 'r', 'u', 'e' ) #define TTAG_ttc FT_MAKE_TAG( 't', 't', 'c', ' ' ) #define TTAG_ttcf FT_MAKE_TAG( 't', 't', 'c', 'f' ) #define TTAG_VDMX FT_MAKE_TAG( 'V', 'D', 'M', 'X' ) #define TTAG_vhea FT_MAKE_TAG( 'v', 'h', 'e', 'a' ) #define TTAG_vmtx FT_MAKE_TAG( 'v', 'm', 't', 'x' ) FT_END_HEADER #endif /* __TTAGS_H__ */ /* END */ --- NEW FILE: ftlist.h --- /***************************************************************************/ /* */ /* ftlist.h */ /* */ /* Generic list support for FreeType (specification). */ /* */ /* Copyright 1996-2001, 2003 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. */ /* */ /***************************************************************************/ /*************************************************************************/ /* */ /* This file implements functions relative to list processing. Its */ /* data structures are defined in `freetype.h'. */ /* */ /*************************************************************************/ #ifndef __FTLIST_H__ #define __FTLIST_H__ #include <ft2build.h> #include FT_FREETYPE_H #ifdef FREETYPE_H #error "freetype.h of FreeType 1 has been loaded!" #error "Please fix the directory search order for header files" #error "so that freetype.h of FreeType 2 is found first." #endif FT_BEGIN_HEADER /*************************************************************************/ /* */ /* <Section> */ /* list_processing */ /* */ /* <Title> */ /* List Processing */ /* */ /* <Abstract> */ /* Simple management of lists. */ /* */ /* <Description> */ /* This section contains various definitions related to list */ /* processing using doubly-linked nodes. */ /* */ /* <Order> */ /* FT_List */ /* FT_ListNode */ /* FT_ListRec */ /* FT_ListNodeRec */ /* */ /* FT_List_Add */ /* FT_List_Insert */ /* FT_List_Find */ /* FT_List_Remove */ /* FT_List_Up */ /* FT_List_Iterate */ /* FT_List_Iterator */ /* FT_List_Finalize */ /* FT_List_Destructor */ /* */ /*************************************************************************/ /*************************************************************************/ /* */ /* <Function> */ /* FT_List_Find */ /* */ /* <Description> */ /* Finds the list node for a given listed object. */ /* */ /* <Input> */ /* list :: A pointer to the parent list. */ /* data :: The address of the listed object. */ /* */ /* <Return> */ /* List node. NULL if it wasn't found. */ /* */ FT_EXPORT( FT_ListNode ) FT_List_Find( FT_List list, void* data ); /*************************************************************************/ /* */ /* <Function> */ /* FT_List_Add */ /* */ /* <Description> */ /* Appends an element to the end of a list. */ /* */ /* <InOut> */ /* list :: A pointer to the parent list. */ /* node :: The node to append. */ /* */ FT_EXPORT( void ) FT_List_Add( FT_List list, FT_ListNode node ); /*************************************************************************/ /* */ /* <Function> */ /* FT_List_Insert */ /* */ /* <Description> */ /* Inserts an element at the head of a list. */ /* */ /* <InOut> */ /* list :: A pointer to parent list. */ /* node :: The node to insert. */ /* */ FT_EXPORT( void ) FT_List_Insert( FT_List list, FT_ListNode node ); /*************************************************************************/ /* */ /* <Function> */ /* FT_List_Remove */ /* */ /* <Description> */ /* Removes a node from a list. This function doesn't check whether */ /* the node is in the list! */ /* */ /* <Input> */ /* node :: The node to remove. */ /* */ /* <InOut> */ /* list :: A pointer to the parent list. */ /* */ FT_EXPORT( void ) FT_List_Remove( FT_List list, FT_ListNode node ); /*************************************************************************/ /* */ /* <Function> */ /* FT_List_Up */ /* */ /* <Description> */ /* Moves a node to the head/top of a list. Used to maintain LRU */ /* lists. */ /* */ /* <InOut> */ /* list :: A pointer to the parent list. */ /* node :: The node to move. */ /* */ FT_EXPORT... [truncated message content] |
|
From: Ehud S. <esh...@us...> - 2006-04-21 16:22:37
|
Update of /cvsroot/roadmap/roadmap_editor/src/freetype/include/freetype/internal In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv22848/include/freetype/internal Added Files: autohint.h ftcalc.h ftdebug.h ftdriver.h ftgloadr.h ftmemory.h ftobjs.h ftrfork.h ftserv.h ftstream.h fttrace.h ftvalid.h internal.h pcftypes.h psaux.h pshints.h sfnt.h t1types.h tttypes.h Log Message: Import freetype sources. --- NEW FILE: ftdebug.h --- /***************************************************************************/ /* */ /* ftdebug.h */ /* */ /* Debugging and logging component (specification). */ /* */ /* Copyright 1996-2001, 2002, 2004 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. */ /* */ /* */ /* IMPORTANT: A description of FreeType's debugging support can be */ /* found in "docs/DEBUG.TXT". Read it if you need to use or */ /* understand this code. */ /* */ /***************************************************************************/ #ifndef __FTDEBUG_H__ #define __FTDEBUG_H__ #include <ft2build.h> #include FT_CONFIG_CONFIG_H #include FT_FREETYPE_H FT_BEGIN_HEADER /* force the definition of FT_DEBUG_LEVEL_ERROR if FT_DEBUG_LEVEL_TRACE */ /* is already defined; this simplifies the following #ifdefs */ /* */ #ifdef FT_DEBUG_LEVEL_TRACE #undef FT_DEBUG_LEVEL_ERROR #define FT_DEBUG_LEVEL_ERROR #endif /*************************************************************************/ /* */ /* Define the trace enums as well as the trace levels array when they */ /* are needed. */ /* */ /*************************************************************************/ #ifdef FT_DEBUG_LEVEL_TRACE #define FT_TRACE_DEF( x ) trace_ ## x , /* defining the enumeration */ typedef enum { #include FT_INTERNAL_TRACE_H trace_count } FT_Trace; /* defining the array of trace levels, provided by `src/base/ftdebug.c' */ extern int ft_trace_levels[trace_count]; #undef FT_TRACE_DEF #endif /* FT_DEBUG_LEVEL_TRACE */ /*************************************************************************/ /* */ /* Define the FT_TRACE macro */ /* */ /* IMPORTANT! */ /* */ /* Each component must define the macro FT_COMPONENT to a valid FT_Trace */ /* value before using any TRACE macro. */ /* */ /*************************************************************************/ #ifdef FT_DEBUG_LEVEL_TRACE #define FT_TRACE( level, varformat ) \ do \ { \ if ( ft_trace_levels[FT_COMPONENT] >= level ) \ FT_Message varformat; \ } while ( 0 ) #else /* !FT_DEBUG_LEVEL_TRACE */ #define FT_TRACE( level, varformat ) do ; while ( 0 ) /* nothing */ #endif /* !FT_DEBUG_LEVEL_TRACE */ /*************************************************************************/ /* */ /* <Function> */ /* FT_Trace_Get_Count */ /* */ /* <Description> */ /* Return the number of available trace components. */ /* */ /* <Return> */ /* The number of trace components. 0 if FreeType 2 is not built with */ /* FT_DEBUG_LEVEL_TRACE definition. */ /* */ /* <Note> */ /* This function may be useful if you want to access elements of */ /* the internal `ft_trace_levels' array by an index. */ /* */ FT_EXPORT( FT_Int ) FT_Trace_Get_Count( void ); /*************************************************************************/ /* */ /* <Function> */ /* FT_Trace_Get_Name */ /* */ /* <Description> */ /* Return the name of a trace component. */ /* */ /* <Input> */ /* The index of the trace component. */ /* */ /* <Return> */ /* The name of the trace component. This is a statically allocated */ /* C string, so do not free it after use. NULL if FreeType 2 is not */ /* built with FT_DEBUG_LEVEL_TRACE definition. */ /* */ /* <Note> */ /* Use @FT_Trace_Get_Count to get the number of available trace */ /* components. */ /* */ /* This function may be useful if you want to control FreeType 2's */ /* debug level in your appliaciton. */ /* */ FT_EXPORT( const char * ) FT_Trace_Get_Name( FT_Int idx ); /*************************************************************************/ /* */ /* You need two opening resp. closing parentheses! */ /* */ /* Example: FT_TRACE0(( "Value is %i", foo )) */ /* */ /*************************************************************************/ #define FT_TRACE0( varformat ) FT_TRACE( 0, varformat ) #define FT_TRACE1( varformat ) FT_TRACE( 1, varformat ) #define FT_TRACE2( varformat ) FT_TRACE( 2, varformat ) #define FT_TRACE3( varformat ) FT_TRACE( 3, varformat ) #define FT_TRACE4( varformat ) FT_TRACE( 4, varformat ) #define FT_TRACE5( varformat ) FT_TRACE( 5, varformat ) #define FT_TRACE6( varformat ) FT_TRACE( 6, varformat ) #define FT_TRACE7( varformat ) FT_TRACE( 7, varformat ) /*************************************************************************/ /* */ /* Define the FT_ERROR macro */ /* */ /*************************************************************************/ #ifdef FT_DEBUG_LEVEL_ERROR #define FT_ERROR( varformat ) FT_Message varformat #else /* !FT_DEBUG_LEVEL_ERROR */ #define FT_ERROR( varformat ) do ; while ( 0 ) /* nothing */ #endif /* !FT_DEBUG_LEVEL_ERROR */ /*************************************************************************/ /* */ /* Define the FT_ASSERT macro */ /* */ /*************************************************************************/ #ifdef FT_DEBUG_LEVEL_ERROR #define FT_ASSERT( condition ) \ do \ { \ if ( !( condition ) ) \ FT_Panic( "assertion failed on line %d of file %s\n", \ __LINE__, __FILE__ ); \ } while ( 0 ) #else /* !FT_DEBUG_LEVEL_ERROR */ #define FT_ASSERT( condition ) do ; while ( 0 ) #endif /* !FT_DEBUG_LEVEL_ERROR */ /*************************************************************************/ /* */ /* Define 'FT_Message' and 'FT_Panic' when needed */ /* */ /*************************************************************************/ #ifdef FT_DEBUG_LEVEL_ERROR #include "stdio.h" /* for vprintf() */ /* print a message */ FT_EXPORT( void ) FT_Message( const char* fmt, ... ); /* print a message and exit */ FT_EXPORT( void ) FT_Panic( const char* fmt, ... ); #endif /* FT_DEBUG_LEVEL_ERROR */ FT_BASE( void ) ft_debug_init( void ); #if defined( _MSC_VER ) /* Visual C++ (and Intel C++) */ /* we disable the warning `conditional expression is constant' here */ /* in order to compile cleanly with the maximum level of warnings */ #pragma warning( disable : 4127 ) #endif /* _MSC_VER */ FT_END_HEADER #endif /* __FTDEBUG_H__ */ /* END */ --- NEW FILE: fttrace.h --- /***************************************************************************/ /* */ /* fttrace.h */ /* */ /* Tracing handling (specification only). */ /* */ /* Copyright 2002, 2004, 2005 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. */ /* */ /***************************************************************************/ /* definitions of trace levels for FreeType 2 */ /* the first level must always be `trace_any' */ FT_TRACE_DEF( any ) /* base components */ FT_TRACE_DEF( calc ) /* calculations (ftcalc.c) */ FT_TRACE_DEF( memory ) /* memory manager (ftobjs.c) */ FT_TRACE_DEF( stream ) /* stream manager (ftstream.c) */ FT_TRACE_DEF( io ) /* i/o interface (ftsystem.c) */ FT_TRACE_DEF( list ) /* list management (ftlist.c) */ FT_TRACE_DEF( init ) /* initialization (ftinit.c) */ FT_TRACE_DEF( objs ) /* base objects (ftobjs.c) */ FT_TRACE_DEF( outline ) /* outline management (ftoutln.c) */ FT_TRACE_DEF( glyph ) /* glyph management (ftglyph.c) */ FT_TRACE_DEF( raster ) /* monochrome rasterizer (ftraster.c) */ FT_TRACE_DEF( smooth ) /* anti-aliasing raster (ftgrays.c) */ FT_TRACE_DEF( mm ) /* MM interface (ftmm.c) */ FT_TRACE_DEF( raccess ) /* resource fork accessor (ftrfork.c) */ /* Cache sub-system */ FT_TRACE_DEF( cache ) /* cache sub-system (ftcache.c, etc.) */ /* SFNT driver components */ FT_TRACE_DEF( sfobjs ) /* SFNT object handler (sfobjs.c) */ FT_TRACE_DEF( ttcmap ) /* charmap handler (ttcmap.c) */ FT_TRACE_DEF( ttkern ) /* kerning handler (ttkern.c) */ FT_TRACE_DEF( ttload ) /* basic TrueType tables (ttload.c) */ FT_TRACE_DEF( ttpost ) /* PS table processing (ttpost.c) */ FT_TRACE_DEF( ttsbit ) /* TrueType sbit handling (ttsbit.c) */ /* TrueType driver components */ FT_TRACE_DEF( ttdriver ) /* TT font driver (ttdriver.c) */ FT_TRACE_DEF( ttgload ) /* TT glyph loader (ttgload.c) */ FT_TRACE_DEF( ttinterp ) /* bytecode interpreter (ttinterp.c) */ FT_TRACE_DEF( ttobjs ) /* TT objects manager (ttobjs.c) */ FT_TRACE_DEF( ttpload ) /* TT data/program loader (ttpload.c) */ FT_TRACE_DEF( ttgxvar ) /* TrueType GX var handler (ttgxvar.c) */ /* Type 1 driver components */ FT_TRACE_DEF( t1driver ) FT_TRACE_DEF( t1gload ) FT_TRACE_DEF( t1hint ) FT_TRACE_DEF( t1load ) FT_TRACE_DEF( t1objs ) FT_TRACE_DEF( t1parse ) /* PostScript helper module `psaux' */ FT_TRACE_DEF( t1decode ) FT_TRACE_DEF( psobjs ) /* PostScript hinting module `pshinter' */ FT_TRACE_DEF( pshrec ) FT_TRACE_DEF( pshalgo1 ) FT_TRACE_DEF( pshalgo2 ) /* Type 2 driver components */ FT_TRACE_DEF( cffdriver ) FT_TRACE_DEF( cffgload ) FT_TRACE_DEF( cffload ) FT_TRACE_DEF( cffobjs ) FT_TRACE_DEF( cffparse ) /* Type 42 driver component */ FT_TRACE_DEF( t42 ) /* CID driver components */ FT_TRACE_DEF( cidafm ) FT_TRACE_DEF( ciddriver ) FT_TRACE_DEF( cidgload ) FT_TRACE_DEF( cidload ) FT_TRACE_DEF( cidobjs ) FT_TRACE_DEF( cidparse ) /* Windows font component */ FT_TRACE_DEF( winfnt ) /* PCF font components */ FT_TRACE_DEF( pcfdriver ) FT_TRACE_DEF( pcfread ) /* BDF font components */ FT_TRACE_DEF( bdfdriver ) FT_TRACE_DEF( bdflib ) /* PFR font component */ FT_TRACE_DEF( pfr ) /* OpenType validation components */ FT_TRACE_DEF( otvmodule ) FT_TRACE_DEF( otvcommon ) FT_TRACE_DEF( otvbase ) FT_TRACE_DEF( otvgdef ) FT_TRACE_DEF( otvgpos ) FT_TRACE_DEF( otvgsub ) FT_TRACE_DEF( otvjstf ) /* END */ --- NEW FILE: ftcalc.h --- /***************************************************************************/ /* */ /* ftcalc.h */ /* */ /* Arithmetic computations (specification). */ /* */ /* Copyright 1996-2001, 2002, 2003, 2004 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. */ /* */ /***************************************************************************/ #ifndef __FTCALC_H__ #define __FTCALC_H__ #include <ft2build.h> #include FT_FREETYPE_H FT_BEGIN_HEADER /*************************************************************************/ /* */ /* <Function> */ /* FT_FixedSqrt */ /* */ /* <Description> */ /* Computes the square root of a 16.16 fixed point value. */ /* */ /* <Input> */ /* x :: The value to compute the root for. */ /* */ /* <Return> */ /* The result of `sqrt(x)'. */ /* */ /* <Note> */ /* This function is not very fast. */ /* */ FT_EXPORT( FT_Int32 ) FT_SqrtFixed( FT_Int32 x ); #define SQRT_32( x ) FT_Sqrt32( x ) /*************************************************************************/ /* */ /* <Function> */ /* FT_Sqrt32 */ /* */ /* <Description> */ /* Computes the square root of an Int32 integer (which will be */ /* handled as an unsigned long value). */ /* */ /* <Input> */ /* x :: The value to compute the root for. */ /* */ /* <Return> */ /* The result of `sqrt(x)'. */ /* */ FT_EXPORT( FT_Int32 ) FT_Sqrt32( FT_Int32 x ); /*************************************************************************/ /* */ /* FT_MulDiv() and FT_MulFix() are declared in freetype.h. */ /* */ /*************************************************************************/ #ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER /*************************************************************************/ /* */ /* <Function> */ /* FT_MulDiv_No_Round */ /* */ /* <Description> */ /* A very simple function used to perform the computation `(a*b)/c' */ /* (without rounding) with maximal accuracy (it uses a 64-bit */ /* intermediate integer whenever necessary). */ /* */ /* This function isn't necessarily as fast as some processor specific */ /* operations, but is at least completely portable. */ /* */ /* <Input> */ /* a :: The first multiplier. */ /* b :: The second multiplier. */ /* c :: The divisor. */ /* */ /* <Return> */ /* The result of `(a*b)/c'. This function never traps when trying to */ /* divide by zero; it simply returns `MaxInt' or `MinInt' depending */ /* on the signs of `a' and `b'. */ /* */ FT_BASE( FT_Long ) FT_MulDiv_No_Round( FT_Long a, FT_Long b, FT_Long c ); #endif /* TT_CONFIG_OPTION_BYTECODE_INTERPRETER */ #define INT_TO_F26DOT6( x ) ( (FT_Long)(x) << 6 ) #define INT_TO_F2DOT14( x ) ( (FT_Long)(x) << 14 ) #define INT_TO_FIXED( x ) ( (FT_Long)(x) << 16 ) #define F2DOT14_TO_FIXED( x ) ( (FT_Long)(x) << 2 ) #define FLOAT_TO_FIXED( x ) ( (FT_Long)( x * 65536.0 ) ) #define ROUND_F26DOT6( x ) ( x >= 0 ? ( ( (x) + 32 ) & -64 ) \ : ( -( ( 32 - (x) ) & -64 ) ) ) FT_END_HEADER #endif /* __FTCALC_H__ */ /* END */ --- NEW FILE: ftserv.h --- /***************************************************************************/ /* */ /* ftserv.h */ /* */ /* The FreeType services (specification only). */ /* */ /* Copyright 2003, 2004, 2005 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. */ /* */ /***************************************************************************/ /*************************************************************************/ /* */ /* Each module can export one or more `services'. Each service is */ /* identified by a constant string and modeled by a pointer; the latter */ /* generally corresponds to a structure containing function pointers. */ /* */ /* Note that a service's data cannot be a mere function pointer because */ /* in C it is possible that function pointers might be implemented */ /* differently than data pointers (e.g. 48 bits instead of 32). */ /* */ /*************************************************************************/ #ifndef __FTSERV_H__ #define __FTSERV_H__ FT_BEGIN_HEADER #if defined( _MSC_VER ) /* Visual C++ (and Intel C++) */ /* we disable the warning `conditional expression is constant' here */ /* in order to compile cleanly with the maximum level of warnings */ #pragma warning( disable : 4127 ) #endif /* _MSC_VER */ /* * @macro: * FT_FACE_FIND_SERVICE * * @description: * This macro is used to look up a service from a face's driver module. * * @input: * face :: * The source face handle. * * id :: * A string describing the service as defined in the service's * header files (e.g. FT_SERVICE_ID_MULTI_MASTERS which expands to * `multi-masters'). It is automatically prefixed with * `FT_SERVICE_ID_'. * * @output: * ptr :: * A variable that receives the service pointer. Will be NULL * if not found. */ #ifdef __cplusplus #define FT_FACE_FIND_SERVICE( face, ptr, id ) \ FT_BEGIN_STMNT \ FT_Module module = FT_MODULE( FT_FACE( face )->driver ); \ FT_Pointer _tmp_ = NULL; \ FT_Pointer* _pptr_ = (FT_Pointer*)&(ptr); \ \ \ if ( module->clazz->get_interface ) \ _tmp_ = module->clazz->get_interface( module, FT_SERVICE_ID_ ## id ); \ *_pptr_ = _tmp_; \ FT_END_STMNT #else /* !C++ */ #define FT_FACE_FIND_SERVICE( face, ptr, id ) \ FT_BEGIN_STMNT \ FT_Module module = FT_MODULE( FT_FACE( face )->driver ); \ FT_Pointer _tmp_ = NULL; \ \ if ( module->clazz->get_interface ) \ _tmp_ = module->clazz->get_interface( module, FT_SERVICE_ID_ ## id ); \ ptr = _tmp_; \ FT_END_STMNT #endif /* !C++ */ /* * @macro: * FT_FACE_FIND_GLOBAL_SERVICE * * @description: * This macro is used to look up a service from all modules. * * @input: * face :: * The source face handle. * * id :: * A string describing the service as defined in the service's * header files (e.g. FT_SERVICE_ID_MULTI_MASTERS which expands to * `multi-masters'). It is automatically prefixed with * `FT_SERVICE_ID_'. * * @output: * ptr :: * A variable that receives the service pointer. Will be NULL * if not found. */ #ifdef __cplusplus #define FT_FACE_FIND_GLOBAL_SERVICE( face, ptr, id ) \ FT_BEGIN_STMNT \ FT_Module module = FT_MODULE( FT_FACE( face )->driver ); \ FT_Pointer _tmp_; \ FT_Pointer* _pptr_ = (FT_Pointer*)&(ptr); \ \ \ _tmp_ = ft_module_get_service( module, FT_SERVICE_ID_ ## id ); \ *_pptr_ = _tmp_; \ FT_END_STMNT #else /* !C++ */ #define FT_FACE_FIND_GLOBAL_SERVICE( face, ptr, id ) \ FT_BEGIN_STMNT \ FT_Module module = FT_MODULE( FT_FACE( face )->driver ); \ FT_Pointer _tmp_; \ \ \ _tmp_ = ft_module_get_service( module, FT_SERVICE_ID_ ## id ); \ ptr = _tmp_; \ FT_END_STMNT #endif /* !C++ */ /*************************************************************************/ /*************************************************************************/ /***** *****/ /***** S E R V I C E D E S C R I P T O R S *****/ /***** *****/ /*************************************************************************/ /*************************************************************************/ /* * The following structure is used to _describe_ a given service * to the library. This is useful to build simple static service lists. */ typedef struct FT_ServiceDescRec_ { const char* serv_id; /* service name */ const void* serv_data; /* service pointer/data */ } FT_ServiceDescRec; typedef const FT_ServiceDescRec* FT_ServiceDesc; /* * Parse a list of FT_ServiceDescRec descriptors and look for * a specific service by ID. Note that the last element in the * array must be { NULL, NULL }, and that the function should * return NULL if the service isn't available. * * This function can be used by modules to implement their * `get_service' method. */ FT_BASE( FT_Pointer ) ft_service_list_lookup( FT_ServiceDesc service_descriptors, const char* service_id ); /*************************************************************************/ /*************************************************************************/ /***** *****/ /***** S E R V I C E S C A C H E *****/ /***** *****/ /*************************************************************************/ /*************************************************************************/ /* * This structure is used to store a cache for several frequently used * services. It is the type of `face->internal->services'. You * should only use FT_FACE_LOOKUP_SERVICE to access it. * * All fields should have the type FT_Pointer to relax compilation * dependencies. We assume the developer isn't completely stupid. * * Each field must be named `service_XXXX' where `XXX' corresponds to * the correct FT_SERVICE_ID_XXXX macro. See the definition of * FT_FACE_LOOKUP_SERVICE below how this is implemented. * */ typedef struct FT_ServiceCacheRec_ { FT_Pointer service_POSTSCRIPT_FONT_NAME; FT_Pointer service_MULTI_MASTERS; FT_Pointer service_GLYPH_DICT; FT_Pointer service_PFR_METRICS; FT_Pointer service_WINFNT; } FT_ServiceCacheRec, *FT_ServiceCache; /* * A magic number used within the services cache. */ #define FT_SERVICE_UNAVAILABLE ((FT_Pointer)-2) /* magic number */ /* * @macro: * FT_FACE_LOOKUP_SERVICE * * @description: * This macro is used to lookup a service from a face's driver module * using its cache. * * @input: * face:: * The source face handle containing the cache. * * field :: * The field name in the cache. * * id :: * The service ID. * * @output: * ptr :: * A variable receiving the service data. NULL if not available. */ #ifdef __cplusplus #define FT_FACE_LOOKUP_SERVICE( face, ptr, id ) \ FT_BEGIN_STMNT \ FT_Pointer svc; \ FT_Pointer* Pptr = (FT_Pointer*)&(ptr); \ \ \ svc = FT_FACE( face )->internal->services. service_ ## id; \ if ( svc == FT_SERVICE_UNAVAILABLE ) \ svc = NULL; \ else if ( svc == NULL ) \ { \ FT_FACE_FIND_SERVICE( face, svc, id ); \ \ FT_FACE( face )->internal->services. service_ ## id = \ (FT_Pointer)( svc != NULL ? svc \ : FT_SERVICE_UNAVAILABLE ); \ } \ *Pptr = svc; \ FT_END_STMNT #else /* !C++ */ #define FT_FACE_LOOKUP_SERVICE( face, ptr, id ) \ FT_BEGIN_STMNT \ FT_Pointer svc; \ \ \ svc = FT_FACE( face )->internal->services. service_ ## id; \ if ( svc == FT_SERVICE_UNAVAILABLE ) \ svc = NULL; \ else if ( svc == NULL ) \ { \ FT_FACE_FIND_SERVICE( face, svc, id ); \ \ FT_FACE( face )->internal->services. service_ ## id = \ (FT_Pointer)( svc != NULL ? svc \ : FT_SERVICE_UNAVAILABLE ); \ } \ ptr = svc; \ FT_END_STMNT #endif /* !C++ */ /* * A macro used to define new service structure types. */ #define FT_DEFINE_SERVICE( name ) \ typedef struct FT_Service_ ## name ## Rec_ \ FT_Service_ ## name ## Rec ; \ typedef struct FT_Service_ ## name ## Rec_ \ const * FT_Service_ ## name ; \ struct FT_Service_ ## name ## Rec_ /* */ /* * The header files containing the services. */ #define FT_SERVICE_BDF_H <freetype/internal/services/svbdf.h> #define FT_SERVICE_GLYPH_DICT_H <freetype/internal/services/svgldict.h> #define FT_SERVICE_MULTIPLE_MASTERS_H <freetype/internal/services/svmm.h> #define FT_SERVICE_OPENTYPE_VALIDATE_H <freetype/internal/services/svotval.h> #define FT_SERVICE_PFR_H <freetype/internal/services/svpfr.h> #define FT_SERVICE_POSTSCRIPT_CMAPS_H <freetype/internal/services/svpscmap.h> #define FT_SERVICE_POSTSCRIPT_INFO_H <freetype/internal/services/svpsinfo.h> #define FT_SERVICE_POSTSCRIPT_NAME_H <freetype/internal/services/svpostnm.h> #define FT_SERVICE_SFNT_H <freetype/internal/services/svsfnt.h> #define FT_SERVICE_TT_CMAP_H <freetype/internal/services/svttcmap.h> #define FT_SERVICE_WINFNT_H <freetype/internal/services/svwinfnt.h> #define FT_SERVICE_XFREE86_NAME_H <freetype/internal/services/svxf86nm.h> /* */ FT_END_HEADER #endif /* __FTSERV_H__ */ /* END */ --- NEW FILE: psaux.h --- /***************************************************************************/ /* */ /* psaux.h */ /* */ /* Auxiliary functions and data structures related to PostScript fonts */ /* (specification). */ /* */ /* Copyright 1996-2001, 2002, 2003, 2004 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. */ /* */ /***************************************************************************/ #ifndef __PSAUX_H__ #define __PSAUX_H__ #include <ft2build.h> #include FT_INTERNAL_OBJECTS_H #include FT_INTERNAL_TYPE1_TYPES_H #include FT_SERVICE_POSTSCRIPT_CMAPS_H FT_BEGIN_HEADER /*************************************************************************/ /*************************************************************************/ /***** *****/ /***** T1_TABLE *****/ /***** *****/ /*************************************************************************/ /*************************************************************************/ typedef struct PS_TableRec_* PS_Table; typedef const struct PS_Table_FuncsRec_* PS_Table_Funcs; /*************************************************************************/ /* */ /* <Struct> */ /* PS_Table_FuncsRec */ /* */ /* <Description> */ /* A set of function pointers to manage PS_Table objects. */ /* */ /* <Fields> */ /* table_init :: Used to initialize a table. */ /* */ /* table_done :: Finalizes resp. destroy a given table. */ /* */ /* table_add :: Adds a new object to a table. */ /* */ /* table_release :: Releases table data, then finalizes it. */ /* */ typedef struct PS_Table_FuncsRec_ { FT_Error (*init)( PS_Table table, FT_Int count, FT_Memory memory ); void (*done)( PS_Table table ); FT_Error (*add)( PS_Table table, FT_Int idx, void* object, FT_PtrDist length ); void (*release)( PS_Table table ); } PS_Table_FuncsRec; /*************************************************************************/ /* */ /* <Struct> */ /* PS_TableRec */ /* */ /* <Description> */ /* A PS_Table is a simple object used to store an array of objects in */ /* a single memory block. */ /* */ /* <Fields> */ /* block :: The address in memory of the growheap's block. This */ /* can change between two object adds, due to */ /* reallocation. */ /* */ /* cursor :: The current top of the grow heap within its block. */ /* */ /* capacity :: The current size of the heap block. Increments by */ /* 1kByte chunks. */ /* */ /* max_elems :: The maximum number of elements in table. */ /* */ /* num_elems :: The current number of elements in table. */ /* */ /* elements :: A table of element addresses within the block. */ /* */ /* lengths :: A table of element sizes within the block. */ /* */ /* memory :: The object used for memory operations */ /* (alloc/realloc). */ /* */ /* funcs :: A table of method pointers for this object. */ /* */ typedef struct PS_TableRec_ { FT_Byte* block; /* current memory block */ FT_Offset cursor; /* current cursor in memory block */ FT_Offset capacity; /* current size of memory block */ FT_Long init; FT_Int max_elems; FT_Int num_elems; FT_Byte** elements; /* addresses of table elements */ FT_PtrDist* lengths; /* lengths of table elements */ FT_Memory memory; PS_Table_FuncsRec funcs; } PS_TableRec; /*************************************************************************/ /*************************************************************************/ /***** *****/ /***** T1 FIELDS & TOKENS *****/ /***** *****/ /*************************************************************************/ /*************************************************************************/ typedef struct PS_ParserRec_* PS_Parser; typedef struct T1_TokenRec_* T1_Token; typedef struct T1_FieldRec_* T1_Field; /* simple enumeration type used to identify token types */ typedef enum T1_TokenType_ { T1_TOKEN_TYPE_NONE = 0, T1_TOKEN_TYPE_ANY, T1_TOKEN_TYPE_STRING, T1_TOKEN_TYPE_ARRAY, /* do not remove */ T1_TOKEN_TYPE_MAX } T1_TokenType; /* a simple structure used to identify tokens */ typedef struct T1_TokenRec_ { FT_Byte* start; /* first character of token in input stream */ FT_Byte* limit; /* first character after the token */ T1_TokenType type; /* type of token */ } T1_TokenRec; /* enumeration type used to identify object fields */ typedef enum T1_FieldType_ { T1_FIELD_TYPE_NONE = 0, T1_FIELD_TYPE_BOOL, T1_FIELD_TYPE_INTEGER, T1_FIELD_TYPE_FIXED, T1_FIELD_TYPE_FIXED_1000, T1_FIELD_TYPE_STRING, T1_FIELD_TYPE_KEY, T1_FIELD_TYPE_BBOX, T1_FIELD_TYPE_INTEGER_ARRAY, T1_FIELD_TYPE_FIXED_ARRAY, T1_FIELD_TYPE_CALLBACK, /* do not remove */ T1_FIELD_TYPE_MAX } T1_FieldType; typedef enum T1_FieldLocation_ { T1_FIELD_LOCATION_CID_INFO, T1_FIELD_LOCATION_FONT_DICT, T1_FIELD_LOCATION_FONT_INFO, T1_FIELD_LOCATION_PRIVATE, T1_FIELD_LOCATION_BBOX, /* do not remove */ T1_FIELD_LOCATION_MAX } T1_FieldLocation; typedef void (*T1_Field_ParseFunc)( FT_Face face, FT_Pointer parser ); /* structure type used to model object fields */ typedef struct T1_FieldRec_ { const char* ident; /* field identifier */ T1_FieldLocation location; T1_FieldType type; /* type of field */ T1_Field_ParseFunc reader; FT_UInt offset; /* offset of field in object */ FT_Byte size; /* size of field in bytes */ FT_UInt array_max; /* maximal number of elements for */ /* array */ FT_UInt count_offset; /* offset of element count for */ /* arrays */ } T1_FieldRec; #define T1_NEW_SIMPLE_FIELD( _ident, _type, _fname ) \ { \ _ident, T1CODE, _type, \ 0, \ FT_FIELD_OFFSET( _fname ), \ FT_FIELD_SIZE( _fname ), \ 0, 0 \ }, #define T1_NEW_CALLBACK_FIELD( _ident, _reader ) \ { \ _ident, T1CODE, T1_FIELD_TYPE_CALLBACK, \ (T1_Field_ParseFunc)_reader, \ 0, 0, \ 0, 0 \ }, #define T1_NEW_TABLE_FIELD( _ident, _type, _fname, _max ) \ { \ _ident, T1CODE, _type, \ 0, \ FT_FIELD_OFFSET( _fname ), \ FT_FIELD_SIZE_DELTA( _fname ), \ _max, \ FT_FIELD_OFFSET( num_ ## _fname ) \ }, #define T1_NEW_TABLE_FIELD2( _ident, _type, _fname, _max ) \ { \ _ident, T1CODE, _type, \ 0, \ FT_FIELD_OFFSET( _fname ), \ FT_FIELD_SIZE_DELTA( _fname ), \ _max, 0 \ }, #define T1_FIELD_BOOL( _ident, _fname ) \ T1_NEW_SIMPLE_FIELD( _ident, T1_FIELD_TYPE_BOOL, _fname ) #define T1_FIELD_NUM( _ident, _fname ) \ T1_NEW_SIMPLE_FIELD( _ident, T1_FIELD_TYPE_INTEGER, _fname ) #define T1_FIELD_FIXED( _ident, _fname ) \ T1_NEW_SIMPLE_FIELD( _ident, T1_FIELD_TYPE_FIXED, _fname ) #define T1_FIELD_FIXED_1000( _ident, _fname ) \ T1_NEW_SIMPLE_FIELD( _ident, T1_FIELD_TYPE_FIXED_1000, _fname ) #define T1_FIELD_STRING( _ident, _fname ) \ T1_NEW_SIMPLE_FIELD( _ident, T1_FIELD_TYPE_STRING, _fname ) #define T1_FIELD_KEY( _ident, _fname ) \ T1_NEW_SIMPLE_FIELD( _ident, T1_FIELD_TYPE_KEY, _fname ) #define T1_FIELD_BBOX( _ident, _fname ) \ T1_NEW_SIMPLE_FIELD( _ident, T1_FIELD_TYPE_BBOX, _fname ) #define T1_FIELD_NUM_TABLE( _ident, _fname, _fmax ) \ T1_NEW_TABLE_FIELD( _ident, T1_FIELD_TYPE_INTEGER_ARRAY, \ _fname, _fmax ) #define T1_FIELD_FIXED_TABLE( _ident, _fname, _fmax ) \ T1_NEW_TABLE_FIELD( _ident, T1_FIELD_TYPE_FIXED_ARRAY, \ _fname, _fmax ) #define T1_FIELD_NUM_TABLE2( _ident, _fname, _fmax ) \ T1_NEW_TABLE_FIELD2( _ident, T1_FIELD_TYPE_INTEGER_ARRAY, \ _fname, _fmax ) #define T1_FIELD_FIXED_TABLE2( _ident, _fname, _fmax ) \ T1_NEW_TABLE_FIELD2( _ident, T1_FIELD_TYPE_FIXED_ARRAY, \ _fname, _fmax ) #define T1_FIELD_CALLBACK( _ident, _name ) \ T1_NEW_CALLBACK_FIELD( _ident, _name ) /*************************************************************************/ /*************************************************************************/ /***** *****/ /***** T1 PARSER *****/ /***** *****/ /*************************************************************************/ /*************************************************************************/ typedef const struct PS_Parser_FuncsRec_* PS_Parser_Funcs; typedef struct PS_Parser_FuncsRec_ { void (*init)( PS_Parser parser, FT_Byte* base, FT_Byte* limit, FT_Memory memory ); void (*done)( PS_Parser parser ); void (*skip_spaces)( PS_Parser parser ); void (*skip_PS_token)( PS_Parser parser ); FT_Long (*to_int)( PS_Parser parser ); FT_Fixed (*to_fixed)( PS_Parser parser, FT_Int power_ten ); FT_Error (*to_bytes)( PS_Parser parser, FT_Byte* bytes, FT_Long max_bytes, FT_Long* pnum_bytes, FT_Bool delimiters ); FT_Int (*to_coord_array)( PS_Parser parser, FT_Int max_coords, FT_Short* coords ); FT_Int (*to_fixed_array)( PS_Parser parser, FT_Int max_values, FT_Fixed* values, FT_Int power_ten ); void (*to_token)( PS_Parser parser, T1_Token token ); void (*to_token_array)( PS_Parser parser, T1_Token tokens, FT_UInt max_tokens, FT_Int* pnum_tokens ); FT_Error (*load_field)( PS_Parser parser, const T1_Field field, void** objects, FT_UInt max_objects, FT_ULong* pflags ); FT_Error (*load_field_table)( PS_Parser parser, const T1_Field field, void** objects, FT_UInt max_objects, FT_ULong* pflags ); } PS_Parser_FuncsRec; /*************************************************************************/ /* */ /* <Struct> */ /* PS_ParserRec */ /* */ /* <Description> */ /* A PS_Parser is an object used to parse a Type 1 font very quickly. */ /* */ /* <Fields> */ /* cursor :: The current position in the text. */ /* */ /* base :: Start of the processed text. */ /* */ /* limit :: End of the processed text. */ /* */ /* error :: The last error returned. */ /* */ /* memory :: The object used for memory operations (alloc/realloc). */ /* */ /* funcs :: A table of functions for the parser. */ /* */ typedef struct PS_ParserRec_ { FT_Byte* cursor; FT_Byte* base; FT_Byte* limit; FT_Error error; FT_Memory memory; PS_Parser_FuncsRec funcs; } PS_ParserRec; /*************************************************************************/ /*************************************************************************/ /***** *****/ /***** T1 BUILDER *****/ /***** *****/ /*************************************************************************/ /*************************************************************************/ typedef struct T1_BuilderRec_* T1_Builder; typedef FT_Error (*T1_Builder_Check_Points_Func)( T1_Builder builder, FT_Int count ); typedef void (*T1_Builder_Add_Point_Func)( T1_Builder builder, FT_Pos x, FT_Pos y, FT_Byte flag ); typedef FT_Error (*T1_Builder_Add_Point1_Func)( T1_Builder builder, FT_Pos x, FT_Pos y ); typedef FT_Error (*T1_Builder_Add_Contour_Func)( T1_Builder builder ); typedef FT_Error (*T1_Builder_Start_Point_Func)( T1_Builder builder, FT_Pos x, FT_Pos y ); typedef void (*T1_Builder_Close_Contour_Func)( T1_Builder builder ); typedef const struct T1_Builder_FuncsRec_* T1_Builder_Funcs; typedef struct T1_Builder_FuncsRec_ { void (*init)( T1_Builder builder, FT_Face face, FT_Size size, FT_GlyphSlot slot, FT_Bool hinting ); void (*done)( T1_Builder builder ); T1_Builder_Check_Points_Func check_points; T1_Builder_Add_Point_Func add_point; T1_Builder_Add_Point1_Func add_point1; T1_Builder_Add_Contour_Func add_contour; T1_Builder_Start_Point_Func start_point; T1_Builder_Close_Contour_Func close_contour; } T1_Builder_FuncsRec; /* an enumeration type to handle charstring parsing states */ typedef enum T1_ParseState_ { T1_Parse_Start, T1_Parse_Have_Width, T1_Parse_Have_Moveto, T1_Parse_Have_Path } T1_ParseState; /*************************************************************************/ /* */ /* <Structure> */ /* T1_BuilderRec */ /* */ /* <Description> */ /* A structure used during glyph loading to store its outline. */ /* */ /* <Fields> */ /* memory :: The current memory object. */ /* */ /* face :: The current face object. */ /* */ /* glyph :: The current glyph slot. */ /* */ /* loader :: XXX */ /* */ /* base :: The base glyph outline. */ /* */ /* current :: The current glyph outline. */ /* */ /* max_points :: maximum points in builder outline */ /* */ /* max_contours :: Maximal number of contours in builder outline. */ /* */ /* last :: The last point position. */ /* */ /* scale_x :: The horizontal scale (FUnits to sub-pixels). */ /* */ /* scale_y :: The vertical scale (FUnits to sub-pixels). */ /* */ /* pos_x :: The horizontal translation (if composite glyph). */ /* */ /* pos_y :: The vertical translation (if composite glyph). */ /* */ /* left_bearing :: The left side bearing point. */ /* */ /* advance :: The horizontal advance vector. */ /* */ /* bbox :: Unused. */ /* */ /* parse_state :: An enumeration which controls the charstring */ /* parsing state. */ /* */ /* load_points :: If this flag is not set, no points are loaded. */ /* */ /* no_recurse :: Set but not used. */ /* */ /* metrics_only :: A boolean indicating that we only want to compute */ /* the metrics of a given glyph, not load all of its */ /* points. */ /* */ /* funcs :: An array of function pointers for the builder. */ /* ... [truncated message content] |
Update of /cvsroot/roadmap/roadmap_editor/src/freetype/src/gzip In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv22848/src/gzip Added Files: adler32.c ftgzip.c infblock.c infcodes.c inflate.c inftrees.c infutil.c zutil.c Log Message: Import freetype sources. --- NEW FILE: inflate.c --- /* inflate.c -- zlib interface to inflate modules * Copyright (C) 1995-2002 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ #include "zutil.h" #include "infblock.h" #define DONE INFLATE_DONE #define BAD INFLATE_BAD typedef enum { METHOD, /* waiting for method byte */ FLAG, /* waiting for flag byte */ DICT4, /* four dictionary check bytes to go */ DICT3, /* three dictionary check bytes to go */ DICT2, /* two dictionary check bytes to go */ DICT1, /* one dictionary check byte to go */ DICT0, /* waiting for inflateSetDictionary */ BLOCKS, /* decompressing blocks */ CHECK4, /* four check bytes to go */ CHECK3, /* three check bytes to go */ CHECK2, /* two check bytes to go */ CHECK1, /* one check byte to go */ DONE, /* finished check, done */ BAD} /* got an error--stay here */ inflate_mode; /* inflate private state */ struct internal_state { /* mode */ inflate_mode mode; /* current inflate mode */ /* mode dependent information */ union { uInt method; /* if FLAGS, method byte */ struct { uLong was; /* computed check value */ uLong need; /* stream check value */ } check; /* if CHECK, check values to compare */ uInt marker; /* if BAD, inflateSync's marker bytes count */ } sub; /* submode */ /* mode independent information */ int nowrap; /* flag for no wrapper */ uInt wbits; /* log2(window size) (8..15, defaults to 15) */ inflate_blocks_statef *blocks; /* current inflate_blocks state */ }; ZEXPORT(int) inflateReset( /* z) */ z_streamp z ) { if (z == Z_NULL || z->state == Z_NULL) return Z_STREAM_ERROR; z->total_in = z->total_out = 0; z->msg = Z_NULL; z->state->mode = z->state->nowrap ? BLOCKS : METHOD; inflate_blocks_reset(z->state->blocks, z, Z_NULL); Tracev((stderr, "inflate: reset\n")); return Z_OK; } ZEXPORT(int) inflateEnd( /* z) */ z_streamp z ) { if (z == Z_NULL || z->state == Z_NULL || z->zfree == Z_NULL) return Z_STREAM_ERROR; if (z->state->blocks != Z_NULL) inflate_blocks_free(z->state->blocks, z); ZFREE(z, z->state); z->state = Z_NULL; Tracev((stderr, "inflate: end\n")); return Z_OK; } ZEXPORT(int) inflateInit2_( /* z, w, version, stream_size) */ z_streamp z, int w, const char *version, int stream_size ) { if (version == Z_NULL || version[0] != ZLIB_VERSION[0] || stream_size != sizeof(z_stream)) return Z_VERSION_ERROR; /* initialize state */ if (z == Z_NULL) return Z_STREAM_ERROR; z->msg = Z_NULL; if (z->zalloc == Z_NULL) { z->zalloc = zcalloc; z->opaque = (voidpf)0; } if (z->zfree == Z_NULL) z->zfree = zcfree; if ((z->state = (struct internal_state FAR *) ZALLOC(z,1,sizeof(struct internal_state))) == Z_NULL) return Z_MEM_ERROR; z->state->blocks = Z_NULL; /* handle undocumented nowrap option (no zlib header or check) */ z->state->nowrap = 0; if (w < 0) { w = - w; z->state->nowrap = 1; } /* set window size */ if (w < 8 || w > 15) { inflateEnd(z); return Z_STREAM_ERROR; } z->state->wbits = (uInt)w; /* create inflate_blocks state */ if ((z->state->blocks = inflate_blocks_new(z, z->state->nowrap ? Z_NULL : adler32, (uInt)1 << w)) == Z_NULL) { inflateEnd(z); return Z_MEM_ERROR; } Tracev((stderr, "inflate: allocated\n")); /* reset state */ inflateReset(z); return Z_OK; } #undef NEEDBYTE #define NEEDBYTE {if(z->avail_in==0)return r;r=f;} #undef NEXTBYTE #define NEXTBYTE (z->avail_in--,z->total_in++,*z->next_in++) ZEXPORT(int) inflate( /* z, f) */ z_streamp z, int f ) { int r; uInt b; if (z == Z_NULL || z->state == Z_NULL || z->next_in == Z_NULL) return Z_STREAM_ERROR; f = f == Z_FINISH ? Z_BUF_ERROR : Z_OK; r = Z_BUF_ERROR; while (1) switch (z->state->mode) { case METHOD: NEEDBYTE if (((z->state->sub.method = NEXTBYTE) & 0xf) != Z_DEFLATED) { z->state->mode = BAD; z->msg = (char*)"unknown compression method"; z->state->sub.marker = 5; /* can't try inflateSync */ break; } if ((z->state->sub.method >> 4) + 8 > z->state->wbits) { z->state->mode = BAD; z->msg = (char*)"invalid window size"; z->state->sub.marker = 5; /* can't try inflateSync */ break; } z->state->mode = FLAG; case FLAG: NEEDBYTE b = NEXTBYTE; if (((z->state->sub.method << 8) + b) % 31) { z->state->mode = BAD; z->msg = (char*)"incorrect header check"; z->state->sub.marker = 5; /* can't try inflateSync */ break; } Tracev((stderr, "inflate: zlib header ok\n")); if (!(b & PRESET_DICT)) { z->state->mode = BLOCKS; break; } z->state->mode = DICT4; case DICT4: NEEDBYTE z->state->sub.check.need = (uLong)NEXTBYTE << 24; z->state->mode = DICT3; case DICT3: NEEDBYTE z->state->sub.check.need += (uLong)NEXTBYTE << 16; z->state->mode = DICT2; case DICT2: NEEDBYTE z->state->sub.check.need += (uLong)NEXTBYTE << 8; z->state->mode = DICT1; case DICT1: NEEDBYTE z->state->sub.check.need += (uLong)NEXTBYTE; z->adler = z->state->sub.check.need; z->state->mode = DICT0; return Z_NEED_DICT; case DICT0: z->state->mode = BAD; z->msg = (char*)"need dictionary"; z->state->sub.marker = 0; /* can try inflateSync */ return Z_STREAM_ERROR; case BLOCKS: r = inflate_blocks(z->state->blocks, z, r); if (r == Z_DATA_ERROR) { z->state->mode = BAD; z->state->sub.marker = 0; /* can try inflateSync */ break; } if (r == Z_OK) r = f; if (r != Z_STREAM_END) return r; r = f; inflate_blocks_reset(z->state->blocks, z, &z->state->sub.check.was); if (z->state->nowrap) { z->state->mode = DONE; break; } z->state->mode = CHECK4; case CHECK4: NEEDBYTE z->state->sub.check.need = (uLong)NEXTBYTE << 24; z->state->mode = CHECK3; case CHECK3: NEEDBYTE z->state->sub.check.need += (uLong)NEXTBYTE << 16; z->state->mode = CHECK2; case CHECK2: NEEDBYTE z->state->sub.check.need += (uLong)NEXTBYTE << 8; z->state->mode = CHECK1; case CHECK1: NEEDBYTE z->state->sub.check.need += (uLong)NEXTBYTE; if (z->state->sub.check.was != z->state->sub.check.need) { z->state->mode = BAD; z->msg = (char*)"incorrect data check"; z->state->sub.marker = 5; /* can't try inflateSync */ break; } Tracev((stderr, "inflate: zlib check ok\n")); z->state->mode = DONE; case DONE: return Z_STREAM_END; case BAD: return Z_DATA_ERROR; default: return Z_STREAM_ERROR; } #ifdef NEED_DUMMY_RETURN return Z_STREAM_ERROR; /* Some dumb compilers complain without this */ #endif } --- NEW FILE: infblock.c --- /* infblock.c -- interpret and process block types to last block * Copyright (C) 1995-2002 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ #include "zutil.h" #include "infblock.h" #include "inftrees.h" #include "infcodes.h" #include "infutil.h" /* simplify the use of the inflate_huft type with some defines */ #define exop word.what.Exop #define bits word.what.Bits /* Table for deflate from PKZIP's appnote.txt. */ local const uInt border[] = { /* Order of the bit length code lengths */ 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; /* Notes beyond the 1.93a appnote.txt: 1. Distance pointers never point before the beginning of the output stream. 2. Distance pointers can point back across blocks, up to 32k away. 3. There is an implied maximum of 7 bits for the bit length table and 15 bits for the actual data. 4. If only one code exists, then it is encoded using one bit. (Zero would be more efficient, but perhaps a little confusing.) If two codes exist, they are coded using one bit each (0 and 1). 5. There is no way of sending zero distance codes--a dummy must be sent if there are none. (History: a pre 2.0 version of PKZIP would store blocks with no distance codes, but this was discovered to be too harsh a criterion.) Valid only for 1.93a. 2.04c does allow zero distance codes, which is sent as one code of zero bits in length. 6. There are up to 286 literal/length codes. Code 256 represents the end-of-block. Note however that the static length tree defines 288 codes just to fill out the Huffman codes. Codes 286 and 287 cannot be used though, since there is no length base or extra bits defined for them. Similarily, there are up to 30 distance codes. However, static trees define 32 codes (all 5 bits) to fill out the Huffman codes, but the last two had better not show up in the data. 7. Unzip can check dynamic Huffman blocks for complete code sets. The exception is that a single code would not be complete (see #4). 8. The five bits following the block type is really the number of literal codes sent minus 257. 9. Length codes 8,16,16 are interpreted as 13 length codes of 8 bits (1+6+6). Therefore, to output three times the length, you output three codes (1+1+1), whereas to output four times the same length, you only need two codes (1+3). Hmm. 10. In the tree reconstruction algorithm, Code = Code + Increment only if BitLength(i) is not zero. (Pretty obvious.) 11. Correction: 4 Bits: # of Bit Length codes - 4 (4 - 19) 12. Note: length code 284 can represent 227-258, but length code 285 really is 258. The last length deserves its own, short code since it gets used a lot in very redundant files. The length 258 is special since 258 - 3 (the min match length) is 255. 13. The literal/length and distance code bit lengths are read as a single stream of lengths. It is possible (and advantageous) for a repeat code (16, 17, or 18) to go across the boundary between the two sets of lengths. */ local void inflate_blocks_reset( /* s, z, c) */ inflate_blocks_statef *s, z_streamp z, uLongf *c ) { if (c != Z_NULL) *c = s->check; if (s->mode == BTREE || s->mode == DTREE) ZFREE(z, s->sub.trees.blens); if (s->mode == CODES) inflate_codes_free(s->sub.decode.codes, z); s->mode = TYPE; s->bitk = 0; s->bitb = 0; s->read = s->write = s->window; if (s->checkfn != Z_NULL) z->adler = s->check = (*s->checkfn)(0L, (const Bytef *)Z_NULL, 0); Tracev((stderr, "inflate: blocks reset\n")); } local inflate_blocks_statef *inflate_blocks_new( /* z, c, w) */ z_streamp z, check_func c, uInt w ) { inflate_blocks_statef *s; if ((s = (inflate_blocks_statef *)ZALLOC (z,1,sizeof(struct inflate_blocks_state))) == Z_NULL) return s; if ((s->hufts = (inflate_huft *)ZALLOC(z, sizeof(inflate_huft), MANY)) == Z_NULL) { ZFREE(z, s); return Z_NULL; } if ((s->window = (Bytef *)ZALLOC(z, 1, w)) == Z_NULL) { ZFREE(z, s->hufts); ZFREE(z, s); return Z_NULL; } s->end = s->window + w; s->checkfn = c; s->mode = TYPE; Tracev((stderr, "inflate: blocks allocated\n")); inflate_blocks_reset(s, z, Z_NULL); return s; } local int inflate_blocks( /* s, z, r) */ inflate_blocks_statef *s, z_streamp z, int r ) { uInt t; /* temporary storage */ uLong b; /* bit buffer */ uInt k; /* bits in bit buffer */ Bytef *p; /* input data pointer */ uInt n; /* bytes available there */ Bytef *q; /* output window write pointer */ uInt m; /* bytes to end of window or read pointer */ /* copy input/output information to locals (UPDATE macro restores) */ LOAD /* process input based on current state */ while (1) switch (s->mode) { case TYPE: NEEDBITS(3) t = (uInt)b & 7; s->last = t & 1; switch (t >> 1) { case 0: /* stored */ Tracev((stderr, "inflate: stored block%s\n", s->last ? " (last)" : "")); DUMPBITS(3) t = k & 7; /* go to byte boundary */ DUMPBITS(t) s->mode = LENS; /* get length of stored block */ break; case 1: /* fixed */ Tracev((stderr, "inflate: fixed codes block%s\n", s->last ? " (last)" : "")); { uInt bl, bd; inflate_huft *tl, *td; inflate_trees_fixed(&bl, &bd, (const inflate_huft**)&tl, (const inflate_huft**)&td, z); s->sub.decode.codes = inflate_codes_new(bl, bd, tl, td, z); if (s->sub.decode.codes == Z_NULL) { r = Z_MEM_ERROR; LEAVE } } DUMPBITS(3) s->mode = CODES; break; case 2: /* dynamic */ Tracev((stderr, "inflate: dynamic codes block%s\n", s->last ? " (last)" : "")); DUMPBITS(3) s->mode = TABLE; break; case 3: /* illegal */ DUMPBITS(3) s->mode = BAD; z->msg = (char*)"invalid block type"; r = Z_DATA_ERROR; LEAVE } break; case LENS: NEEDBITS(32) if ((((~b) >> 16) & 0xffff) != (b & 0xffff)) { s->mode = BAD; z->msg = (char*)"invalid stored block lengths"; r = Z_DATA_ERROR; LEAVE } s->sub.left = (uInt)b & 0xffff; b = k = 0; /* dump bits */ Tracev((stderr, "inflate: stored length %u\n", s->sub.left)); s->mode = s->sub.left ? STORED : (s->last ? DRY : TYPE); break; case STORED: if (n == 0) LEAVE NEEDOUT t = s->sub.left; if (t > n) t = n; if (t > m) t = m; zmemcpy(q, p, t); p += t; n -= t; q += t; m -= t; if ((s->sub.left -= t) != 0) break; Tracev((stderr, "inflate: stored end, %lu total out\n", z->total_out + (q >= s->read ? q - s->read : (s->end - s->read) + (q - s->window)))); s->mode = s->last ? DRY : TYPE; break; case TABLE: NEEDBITS(14) s->sub.trees.table = t = (uInt)b & 0x3fff; #ifndef PKZIP_BUG_WORKAROUND if ((t & 0x1f) > 29 || ((t >> 5) & 0x1f) > 29) { s->mode = BAD; z->msg = (char*)"too many length or distance symbols"; r = Z_DATA_ERROR; LEAVE } #endif t = 258 + (t & 0x1f) + ((t >> 5) & 0x1f); if ((s->sub.trees.blens = (uIntf*)ZALLOC(z, t, sizeof(uInt))) == Z_NULL) { r = Z_MEM_ERROR; LEAVE } DUMPBITS(14) s->sub.trees.index = 0; Tracev((stderr, "inflate: table sizes ok\n")); s->mode = BTREE; case BTREE: while (s->sub.trees.index < 4 + (s->sub.trees.table >> 10)) { NEEDBITS(3) s->sub.trees.blens[border[s->sub.trees.index++]] = (uInt)b & 7; DUMPBITS(3) } while (s->sub.trees.index < 19) s->sub.trees.blens[border[s->sub.trees.index++]] = 0; s->sub.trees.bb = 7; t = inflate_trees_bits(s->sub.trees.blens, &s->sub.trees.bb, &s->sub.trees.tb, s->hufts, z); if (t != Z_OK) { r = t; if (r == Z_DATA_ERROR) { ZFREE(z, s->sub.trees.blens); s->mode = BAD; } LEAVE } s->sub.trees.index = 0; Tracev((stderr, "inflate: bits tree ok\n")); s->mode = DTREE; case DTREE: while (t = s->sub.trees.table, s->sub.trees.index < 258 + (t & 0x1f) + ((t >> 5) & 0x1f)) { inflate_huft *h; uInt i, j, c; t = s->sub.trees.bb; NEEDBITS(t) h = s->sub.trees.tb + ((uInt)b & inflate_mask[t]); t = h->bits; c = h->base; if (c < 16) { DUMPBITS(t) s->sub.trees.blens[s->sub.trees.index++] = c; } else /* c == 16..18 */ { i = c == 18 ? 7 : c - 14; j = c == 18 ? 11 : 3; NEEDBITS(t + i) DUMPBITS(t) j += (uInt)b & inflate_mask[i]; DUMPBITS(i) i = s->sub.trees.index; t = s->sub.trees.table; if (i + j > 258 + (t & 0x1f) + ((t >> 5) & 0x1f) || (c == 16 && i < 1)) { ZFREE(z, s->sub.trees.blens); s->mode = BAD; z->msg = (char*)"invalid bit length repeat"; r = Z_DATA_ERROR; LEAVE } c = c == 16 ? s->sub.trees.blens[i - 1] : 0; do { s->sub.trees.blens[i++] = c; } while (--j); s->sub.trees.index = i; } } s->sub.trees.tb = Z_NULL; { uInt bl, bd; inflate_huft *tl, *td; inflate_codes_statef *c; bl = 9; /* must be <= 9 for lookahead assumptions */ bd = 6; /* must be <= 9 for lookahead assumptions */ t = s->sub.trees.table; t = inflate_trees_dynamic(257 + (t & 0x1f), 1 + ((t >> 5) & 0x1f), s->sub.trees.blens, &bl, &bd, &tl, &td, s->hufts, z); if (t != Z_OK) { if (t == (uInt)Z_DATA_ERROR) { ZFREE(z, s->sub.trees.blens); s->mode = BAD; } r = t; LEAVE } Tracev((stderr, "inflate: trees ok\n")); if ((c = inflate_codes_new(bl, bd, tl, td, z)) == Z_NULL) { r = Z_MEM_ERROR; LEAVE } s->sub.decode.codes = c; } ZFREE(z, s->sub.trees.blens); s->mode = CODES; case CODES: UPDATE if ((r = inflate_codes(s, z, r)) != Z_STREAM_END) return inflate_flush(s, z, r); r = Z_OK; inflate_codes_free(s->sub.decode.codes, z); LOAD Tracev((stderr, "inflate: codes end, %lu total out\n", z->total_out + (q >= s->read ? q - s->read : (s->end - s->read) + (q - s->window)))); if (!s->last) { s->mode = TYPE; break; } s->mode = DRY; case DRY: FLUSH if (s->read != s->write) LEAVE s->mode = DONE; case DONE: r = Z_STREAM_END; LEAVE case BAD: r = Z_DATA_ERROR; LEAVE default: r = Z_STREAM_ERROR; LEAVE } #ifdef NEED_DUMMY_RETURN return 0; #endif } local int inflate_blocks_free( /* s, z) */ inflate_blocks_statef *s, z_streamp z ) { inflate_blocks_reset(s, z, Z_NULL); ZFREE(z, s->window); ZFREE(z, s->hufts); ZFREE(z, s); Tracev((stderr, "inflate: blocks freed\n")); return Z_OK; } --- NEW FILE: infutil.c --- /* inflate_util.c -- data and routines common to blocks and codes * Copyright (C) 1995-2002 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ #include "zutil.h" #include "infblock.h" #include "inftrees.h" #include "infcodes.h" #include "infutil.h" /* And'ing with mask[n] masks the lower n bits */ local const uInt inflate_mask[17] = { 0x0000, 0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff, 0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff }; /* copy as much as possible from the sliding window to the output area */ local int inflate_flush( /* s, z, r) */ inflate_blocks_statef *s, z_streamp z, int r ) { uInt n; Bytef *p; Bytef *q; /* local copies of source and destination pointers */ p = z->next_out; q = s->read; /* compute number of bytes to copy as far as end of window */ n = (uInt)((q <= s->write ? s->write : s->end) - q); if (n > z->avail_out) n = z->avail_out; if (n && r == Z_BUF_ERROR) r = Z_OK; /* update counters */ z->avail_out -= n; z->total_out += n; /* update check information */ if (s->checkfn != Z_NULL) z->adler = s->check = (*s->checkfn)(s->check, q, n); /* copy as far as end of window */ zmemcpy(p, q, n); p += n; q += n; /* see if more to copy at beginning of window */ if (q == s->end) { /* wrap pointers */ q = s->window; if (s->write == s->end) s->write = s->window; /* compute bytes to copy */ n = (uInt)(s->write - q); if (n > z->avail_out) n = z->avail_out; if (n && r == Z_BUF_ERROR) r = Z_OK; /* update counters */ z->avail_out -= n; z->total_out += n; /* update check information */ if (s->checkfn != Z_NULL) z->adler = s->check = (*s->checkfn)(s->check, q, n); /* copy */ zmemcpy(p, q, n); p += n; q += n; } /* update pointers */ z->next_out = p; s->read = q; /* done */ return r; } --- NEW FILE: infcodes.c --- /* infcodes.c -- process literals and length/distance pairs * Copyright (C) 1995-2002 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ #include "zutil.h" #include "inftrees.h" #include "infblock.h" #include "infcodes.h" #include "infutil.h" /* simplify the use of the inflate_huft type with some defines */ #define exop word.what.Exop #define bits word.what.Bits typedef enum { /* waiting for "i:"=input, "o:"=output, "x:"=nothing */ START, /* x: set up for LEN */ LEN, /* i: get length/literal/eob next */ LENEXT, /* i: getting length extra (have base) */ DIST, /* i: get distance next */ DISTEXT, /* i: getting distance extra */ COPY, /* o: copying bytes in window, waiting for space */ LIT, /* o: got literal, waiting for output space */ WASH, /* o: got eob, possibly still output waiting */ END, /* x: got eob and all data flushed */ BADCODE} /* x: got error */ inflate_codes_mode; /* inflate codes private state */ struct inflate_codes_state { /* mode */ inflate_codes_mode mode; /* current inflate_codes mode */ /* mode dependent information */ uInt len; union { struct { inflate_huft *tree; /* pointer into tree */ uInt need; /* bits needed */ } code; /* if LEN or DIST, where in tree */ uInt lit; /* if LIT, literal */ struct { uInt get; /* bits to get for extra */ uInt dist; /* distance back to copy from */ } copy; /* if EXT or COPY, where and how much */ } sub; /* submode */ /* mode independent information */ Byte lbits; /* ltree bits decoded per branch */ Byte dbits; /* dtree bits decoder per branch */ inflate_huft *ltree; /* literal/length/eob tree */ inflate_huft *dtree; /* distance tree */ }; local inflate_codes_statef *inflate_codes_new( /* bl, bd, tl, td, z) */ uInt bl, uInt bd, inflate_huft *tl, inflate_huft *td, /* need separate declaration for Borland C++ */ z_streamp z ) { inflate_codes_statef *c; if ((c = (inflate_codes_statef *) ZALLOC(z,1,sizeof(struct inflate_codes_state))) != Z_NULL) { c->mode = START; c->lbits = (Byte)bl; c->dbits = (Byte)bd; c->ltree = tl; c->dtree = td; Tracev((stderr, "inflate: codes new\n")); } return c; } local int inflate_codes( /* s, z, r) */ inflate_blocks_statef *s, z_streamp z, int r ) { uInt j; /* temporary storage */ inflate_huft *t; /* temporary pointer */ uInt e; /* extra bits or operation */ uLong b; /* bit buffer */ uInt k; /* bits in bit buffer */ Bytef *p; /* input data pointer */ uInt n; /* bytes available there */ Bytef *q; /* output window write pointer */ uInt m; /* bytes to end of window or read pointer */ Bytef *f; /* pointer to copy strings from */ inflate_codes_statef *c = s->sub.decode.codes; /* codes state */ /* copy input/output information to locals (UPDATE macro restores) */ LOAD /* process input and output based on current state */ while (1) switch (c->mode) { /* waiting for "i:"=input, "o:"=output, "x:"=nothing */ case START: /* x: set up for LEN */ #ifndef SLOW if (m >= 258 && n >= 10) { UPDATE r = inflate_fast(c->lbits, c->dbits, c->ltree, c->dtree, s, z); LOAD if (r != Z_OK) { c->mode = r == Z_STREAM_END ? WASH : BADCODE; break; } } #endif /* !SLOW */ c->sub.code.need = c->lbits; c->sub.code.tree = c->ltree; c->mode = LEN; case LEN: /* i: get length/literal/eob next */ j = c->sub.code.need; NEEDBITS(j) t = c->sub.code.tree + ((uInt)b & inflate_mask[j]); DUMPBITS(t->bits) e = (uInt)(t->exop); if (e == 0) /* literal */ { c->sub.lit = t->base; Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ? "inflate: literal '%c'\n" : "inflate: literal 0x%02x\n", t->base)); c->mode = LIT; break; } if (e & 16) /* length */ { c->sub.copy.get = e & 15; c->len = t->base; c->mode = LENEXT; break; } if ((e & 64) == 0) /* next table */ { c->sub.code.need = e; c->sub.code.tree = t + t->base; break; } if (e & 32) /* end of block */ { Tracevv((stderr, "inflate: end of block\n")); c->mode = WASH; break; } c->mode = BADCODE; /* invalid code */ z->msg = (char*)"invalid literal/length code"; r = Z_DATA_ERROR; LEAVE case LENEXT: /* i: getting length extra (have base) */ j = c->sub.copy.get; NEEDBITS(j) c->len += (uInt)b & inflate_mask[j]; DUMPBITS(j) c->sub.code.need = c->dbits; c->sub.code.tree = c->dtree; Tracevv((stderr, "inflate: length %u\n", c->len)); c->mode = DIST; case DIST: /* i: get distance next */ j = c->sub.code.need; NEEDBITS(j) t = c->sub.code.tree + ((uInt)b & inflate_mask[j]); DUMPBITS(t->bits) e = (uInt)(t->exop); if (e & 16) /* distance */ { c->sub.copy.get = e & 15; c->sub.copy.dist = t->base; c->mode = DISTEXT; break; } if ((e & 64) == 0) /* next table */ { c->sub.code.need = e; c->sub.code.tree = t + t->base; break; } c->mode = BADCODE; /* invalid code */ z->msg = (char*)"invalid distance code"; r = Z_DATA_ERROR; LEAVE case DISTEXT: /* i: getting distance extra */ j = c->sub.copy.get; NEEDBITS(j) c->sub.copy.dist += (uInt)b & inflate_mask[j]; DUMPBITS(j) Tracevv((stderr, "inflate: distance %u\n", c->sub.copy.dist)); c->mode = COPY; case COPY: /* o: copying bytes in window, waiting for space */ f = q - c->sub.copy.dist; while (f < s->window) /* modulo window size-"while" instead */ f += s->end - s->window; /* of "if" handles invalid distances */ while (c->len) { NEEDOUT OUTBYTE(*f++) if (f == s->end) f = s->window; c->len--; } c->mode = START; break; case LIT: /* o: got literal, waiting for output space */ NEEDOUT OUTBYTE(c->sub.lit) c->mode = START; break; case WASH: /* o: got eob, possibly more output */ if (k > 7) /* return unused byte, if any */ { Assert(k < 16, "inflate_codes grabbed too many bytes") k -= 8; n++; p--; /* can always return one */ } FLUSH if (s->read != s->write) LEAVE c->mode = END; case END: r = Z_STREAM_END; LEAVE case BADCODE: /* x: got error */ r = Z_DATA_ERROR; LEAVE default: r = Z_STREAM_ERROR; LEAVE } #ifdef NEED_DUMMY_RETURN return Z_STREAM_ERROR; /* Some dumb compilers complain without this */ #endif } local void inflate_codes_free( /* c, z) */ inflate_codes_statef *c, z_streamp z ) { ZFREE(z, c); Tracev((stderr, "inflate: codes free\n")); } --- NEW FILE: inftrees.c --- /* inftrees.c -- generate Huffman trees for efficient decoding * Copyright (C) 1995-2002 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ #include "zutil.h" #include "inftrees.h" #if !defined(BUILDFIXED) && !defined(STDC) # define BUILDFIXED /* non ANSI compilers may not accept inffixed.h */ #endif #if 0 local const char inflate_copyright[] = " inflate 1.1.4 Copyright 1995-2002 Mark Adler "; #endif /* If you use the zlib library in a product, an acknowledgment is welcome in the documentation of your product. If for some reason you cannot include such an acknowledgment, I would appreciate that you keep this copyright string in the executable of your product. */ /* simplify the use of the inflate_huft type with some defines */ #define exop word.what.Exop #define bits word.what.Bits local int huft_build OF(( uIntf *, /* code lengths in bits */ uInt, /* number of codes */ uInt, /* number of "simple" codes */ const uIntf *, /* list of base values for non-simple codes */ const uIntf *, /* list of extra bits for non-simple codes */ inflate_huft * FAR*,/* result: starting table */ uIntf *, /* maximum lookup bits (returns actual) */ inflate_huft *, /* space for trees */ uInt *, /* hufts used in space */ uIntf * )); /* space for values */ /* Tables for deflate from PKZIP's appnote.txt. */ local const uInt cplens[31] = { /* Copy lengths for literal codes 257..285 */ 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0}; /* see note #13 above about 258 */ local const uInt cplext[31] = { /* Extra bits for literal codes 257..285 */ 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 112, 112}; /* 112==invalid */ local const uInt cpdist[30] = { /* Copy offsets for distance codes 0..29 */ 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577}; local const uInt cpdext[30] = { /* Extra bits for distance codes */ 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13}; /* Huffman code decoding is performed using a multi-level table lookup. The fastest way to decode is to simply build a lookup table whose size is determined by the longest code. However, the time it takes to build this table can also be a factor if the data being decoded is not very long. The most common codes are necessarily the shortest codes, so those codes dominate the decoding time, and hence the speed. The idea is you can have a shorter table that decodes the shorter, more probable codes, and then point to subsidiary tables for the longer codes. The time it costs to decode the longer codes is then traded against the time it takes to make longer tables. This results of this trade are in the variables lbits and dbits below. lbits is the number of bits the first level table for literal/ length codes can decode in one step, and dbits is the same thing for the distance codes. Subsequent tables are also less than or equal to those sizes. These values may be adjusted either when all of the codes are shorter than that, in which case the longest code length in bits is used, or when the shortest code is *longer* than the requested table size, in which case the length of the shortest code in bits is used. There are two different values for the two tables, since they code a different number of possibilities each. The literal/length table codes 286 possible values, or in a flat code, a little over eight bits. The distance table codes 30 possible values, or a little less than five bits, flat. The optimum values for speed end up being about one bit more than those, so lbits is 8+1 and dbits is 5+1. The optimum values may differ though from machine to machine, and possibly even between compilers. Your mileage may vary. */ /* If BMAX needs to be larger than 16, then h and x[] should be uLong. */ #define BMAX 15 /* maximum bit length of any code */ local int huft_build( /* b, n, s, d, e, t, m, hp, hn, v) */ uIntf *b, /* code lengths in bits (all assumed <= BMAX) */ uInt n, /* number of codes (assumed <= 288) */ uInt s, /* number of simple-valued codes (0..s-1) */ const uIntf *d, /* list of base values for non-simple codes */ const uIntf *e, /* list of extra bits for non-simple codes */ inflate_huft * FAR *t, /* result: starting table */ uIntf *m, /* maximum lookup bits, returns actual */ inflate_huft *hp, /* space for trees */ uInt *hn, /* hufts used in space */ uIntf *v /* working area: values in order of bit length */ /* Given a list of code lengths and a maximum table size, make a set of tables to decode that set of codes. Return Z_OK on success, Z_BUF_ERROR if the given code set is incomplete (the tables are still built in this case), or Z_DATA_ERROR if the input is invalid. */ ) { uInt a; /* counter for codes of length k */ uInt c[BMAX+1]; /* bit length count table */ uInt f; /* i repeats in table every f entries */ int g; /* maximum code length */ int h; /* table level */ register uInt i; /* counter, current code */ register uInt j; /* counter */ register int k; /* number of bits in current code */ int l; /* bits per table (returned in m) */ uInt mask; /* (1 << w) - 1, to avoid cc -O bug on HP */ register uIntf *p; /* pointer into c[], b[], or v[] */ inflate_huft *q; /* points to current table */ struct inflate_huft_s r; /* table entry for structure assignment */ inflate_huft *u[BMAX]; /* table stack */ register int w; /* bits before this table == (l * h) */ uInt x[BMAX+1]; /* bit offsets, then code stack */ uIntf *xp; /* pointer into x */ int y; /* number of dummy codes added */ uInt z; /* number of entries in current table */ /* Generate counts for each bit length */ p = c; #define C0 *p++ = 0; #define C2 C0 C0 C0 C0 #define C4 C2 C2 C2 C2 C4 /* clear c[]--assume BMAX+1 is 16 */ p = b; i = n; do { c[*p++]++; /* assume all entries <= BMAX */ } while (--i); if (c[0] == n) /* null input--all zero length codes */ { *t = (inflate_huft *)Z_NULL; *m = 0; return Z_OK; } /* Find minimum and maximum length, bound *m by those */ l = *m; for (j = 1; j <= BMAX; j++) if (c[j]) break; k = j; /* minimum code length */ if ((uInt)l < j) l = j; for (i = BMAX; i; i--) if (c[i]) break; g = i; /* maximum code length */ if ((uInt)l > i) l = i; *m = l; /* Adjust last length count to fill out codes, if needed */ for (y = 1 << j; j < i; j++, y <<= 1) if ((y -= c[j]) < 0) return Z_DATA_ERROR; if ((y -= c[i]) < 0) return Z_DATA_ERROR; c[i] += y; /* Generate starting offsets into the value table for each length */ x[1] = j = 0; p = c + 1; xp = x + 2; while (--i) { /* note that i == g from above */ *xp++ = (j += *p++); } /* Make a table of values in order of bit lengths */ p = b; i = 0; do { if ((j = *p++) != 0) v[x[j]++] = i; } while (++i < n); n = x[g]; /* set n to length of v */ /* Generate the Huffman codes and for each, make the table entries */ x[0] = i = 0; /* first Huffman code is zero */ p = v; /* grab values in bit order */ h = -1; /* no tables yet--level -1 */ w = -l; /* bits decoded == (l * h) */ u[0] = (inflate_huft *)Z_NULL; /* just to keep compilers happy */ q = (inflate_huft *)Z_NULL; /* ditto */ z = 0; /* ditto */ /* go through the bit lengths (k already is bits in shortest code) */ for (; k <= g; k++) { a = c[k]; while (a--) { /* here i is the Huffman code of length k bits for value *p */ /* make tables up to required level */ while (k > w + l) { h++; w += l; /* previous table always l bits */ /* compute minimum size table less than or equal to l bits */ z = g - w; z = z > (uInt)l ? (uInt)l : z; /* table size upper limit */ if ((f = 1 << (j = k - w)) > a + 1) /* try a k-w bit table */ { /* too few codes for k-w bit table */ f -= a + 1; /* deduct codes from patterns left */ xp = c + k; if (j < z) while (++j < z) /* try smaller tables up to z bits */ { if ((f <<= 1) <= *++xp) break; /* enough codes to use up j bits */ f -= *xp; /* else deduct codes from patterns */ } } z = 1 << j; /* table entries for j-bit table */ /* allocate new table */ if (*hn + z > MANY) /* (note: doesn't matter for fixed) */ return Z_DATA_ERROR; /* overflow of MANY */ u[h] = q = hp + *hn; *hn += z; /* connect to last table, if there is one */ if (h) { x[h] = i; /* save pattern for backing up */ r.bits = (Byte)l; /* bits to dump before this table */ r.exop = (Byte)j; /* bits in this table */ j = i >> (w - l); r.base = (uInt)(q - u[h-1] - j); /* offset to this table */ u[h-1][j] = r; /* connect to last table */ } else *t = q; /* first table is returned result */ } /* set up table entry in r */ r.bits = (Byte)(k - w); if (p >= v + n) r.exop = 128 + 64; /* out of values--invalid code */ else if (*p < s) { r.exop = (Byte)(*p < 256 ? 0 : 32 + 64); /* 256 is end-of-block */ r.base = *p++; /* simple code is just the value */ } else { r.exop = (Byte)(e[*p - s] + 16 + 64);/* non-simple--look up in lists */ r.base = d[*p++ - s]; } /* fill code-like entries with r */ f = 1 << (k - w); for (j = i >> w; j < z; j += f) q[j] = r; /* backwards increment the k-bit code i */ for (j = 1 << (k - 1); i & j; j >>= 1) i ^= j; i ^= j; /* backup over finished tables */ mask = (1 << w) - 1; /* needed on HP, cc -O bug */ while ((i & mask) != x[h]) { h--; /* don't need to update q */ w -= l; mask = (1 << w) - 1; } } } /* Return Z_BUF_ERROR if we were given an incomplete table */ return y != 0 && g != 1 ? Z_BUF_ERROR : Z_OK; } local int inflate_trees_bits( /* c, bb, tb, hp, z) */ uIntf *c, /* 19 code lengths */ uIntf *bb, /* bits tree desired/actual depth */ inflate_huft * FAR *tb, /* bits tree result */ inflate_huft *hp, /* space for trees */ z_streamp z /* for messages */ ) { int r; uInt hn = 0; /* hufts used in space */ uIntf *v; /* work area for huft_build */ if ((v = (uIntf*)ZALLOC(z, 19, sizeof(uInt))) == Z_NULL) return Z_MEM_ERROR; r = huft_build(c, 19, 19, (uIntf*)Z_NULL, (uIntf*)Z_NULL, tb, bb, hp, &hn, v); if (r == Z_DATA_ERROR) z->msg = (char*)"oversubscribed dynamic bit lengths tree"; else if (r == Z_BUF_ERROR || *bb == 0) { z->msg = (char*)"incomplete dynamic bit lengths tree"; r = Z_DATA_ERROR; } ZFREE(z, v); return r; } local int inflate_trees_dynamic( /* nl, nd, c, bl, bd, tl, td, hp, z) */ uInt nl, /* number of literal/length codes */ uInt nd, /* number of distance codes */ uIntf *c, /* that many (total) code lengths */ uIntf *bl, /* literal desired/actual bit depth */ uIntf *bd, /* distance desired/actual bit depth */ inflate_huft * FAR *tl, /* literal/length tree result */ inflate_huft * FAR *td, /* distance tree result */ inflate_huft *hp, /* space for trees */ z_streamp z /* for messages */ ) { int r; uInt hn = 0; /* hufts used in space */ uIntf *v; /* work area for huft_build */ /* allocate work area */ if ((v = (uIntf*)ZALLOC(z, 288, sizeof(uInt))) == Z_NULL) return Z_MEM_ERROR; /* build literal/length tree */ r = huft_build(c, nl, 257, cplens, cplext, tl, bl, hp, &hn, v); if (r != Z_OK || *bl == 0) { if (r == Z_DATA_ERROR) z->msg = (char*)"oversubscribed literal/length tree"; else if (r != Z_MEM_ERROR) { z->msg = (char*)"incomplete literal/length tree"; r = Z_DATA_ERROR; } ZFREE(z, v); return r; } /* build distance tree */ r = huft_build(c + nl, nd, 0, cpdist, cpdext, td, bd, hp, &hn, v); if (r != Z_OK || (*bd == 0 && nl > 257)) { if (r == Z_DATA_ERROR) z->msg = (char*)"oversubscribed distance tree"; else if (r == Z_BUF_ERROR) { #ifdef PKZIP_BUG_WORKAROUND r = Z_OK; } #else z->msg = (char*)"incomplete distance tree"; r = Z_DATA_ERROR; } else if (r != Z_MEM_ERROR) { z->msg = (char*)"empty distance tree with lengths"; r = Z_DATA_ERROR; } ZFREE(z, v); return r; #endif } /* done */ ZFREE(z, v); return Z_OK; } /* build fixed tables only once--keep them here */ #ifdef BUILDFIXED local int fixed_built = 0; #define FIXEDH 544 /* number of hufts used by fixed tables */ local inflate_huft fixed_mem[FIXEDH]; local uInt fixed_bl; local uInt fixed_bd; local inflate_huft *fixed_tl; local inflate_huft *fixed_td; #else #include "inffixed.h" #endif local int inflate_trees_fixed( /* bl, bd, tl, td, z) */ uIntf *bl, /* literal desired/actual bit depth */ uIntf *bd, /* distance desired/actual bit depth */ const inflate_huft * FAR *tl, /* literal/length tree result */ const inflate_huft * FAR *td, /* distance tree result */ z_streamp z /* for memory allocation */ ) { #ifdef BUILDFIXED /* build fixed tables if not already */ if (!fixed_built) { int k; /* temporary variable */ uInt f = 0; /* number of hufts used in fixed_mem */ uIntf *c; /* length list for huft_build */ uIntf *v; /* work area for huft_build */ /* allocate memory */ if ((c = (uIntf*)ZALLOC(z, 288, sizeof(uInt))) == Z_NULL) return Z_MEM_ERROR; if ((v = (uIntf*)ZALLOC(z, 288, sizeof(uInt))) == Z_NULL) { ZFREE(z, c); return Z_MEM_ERROR; } /* literal table */ for (k = 0; k < 144; k++) c[k] = 8; for (; k < 256; k++) c[k] = 9; for (; k < 280; k++) c[k] = 7; for (; k < 288; k++) c[k] = 8; fixed_bl = 9; huft_build(c, 288, 257, cplens, cplext, &fixed_tl, &fixed_bl, fixed_mem, &f, v); /* distance table */ for (k = 0; k < 30; k++) c[k] = 5; fixed_bd = 5; huft_build(c, 30, 0, cpdist, cpdext, &fixed_td, &fixed_bd, fixed_mem, &f, v); /* done */ ZFREE(z, v); ZFREE(z, c); fixed_built = 1; } #else FT_UNUSED(z); #endif *bl = fixed_bl; *bd = fixed_bd; *tl = fixed_tl; *td = fixed_td; return Z_OK; } --- NEW FILE: ftgzip.c --- /***************************************************************************/ /* */ /* ftgzip.c */ /* */ /* FreeType support for .gz compressed files. */ /* */ /* This optional component relies on zlib. It should mainly be used to */ /* parse compressed PCF fonts, as found with many X11 server */ /* distributions. */ /* */ /* Copyright 2002, 2003, 2004, 2005 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. */ /* */ /***************************************************************************/ //#define FT_BITMAP_H #include <ft2build.h> #include FT_INTERNAL_MEMORY_H #include FT_INTERNAL_STREAM_H #include FT_INTERNAL_DEBUG_H #include <string.h> #include FT_MODULE_ERRORS_H #undef __FTERRORS_H__ #define FT_ERR_PREFIX Gzip_Err_ #define FT_ERR_BASE FT_Mod_Err_Gzip #include FT_ERRORS_H #ifdef FT_CONFIG_OPTION_USE_ZLIB #ifdef FT_CONFIG_OPTION_SYSTEM_ZLIB #include <zlib.h> #else /* !FT_CONFIG_OPTION_SYSTEM_ZLIB */ /* In this case, we include our own modified sources of the ZLib */ /* within the "ftgzip" component. The modifications were necessary */ /* to #include all files without conflicts, as well as preventing */ /* the definition of "extern" functions that may cause linking */ /* conflicts when a program is linked with both FreeType and the */ /* original ZLib. */ #define NO_DUMMY_DECL #define MY_ZCALLOC #include "zlib.h" #undef SLOW #define SLOW 1 /* we can't use asm-optimized sources here! */ /* Urgh. `inflate_mask' must not be declared twice -- C++ doesn't like this. We temporarily disable it and load all necessary header files. */ #define NO_INFLATE_MASK #include "zutil.h" #include "inftrees.h" #include "infblock.h" #include "infcodes.h" #include "infutil.h" #undef NO_INFLATE_MASK /* infutil.c must be included before infcodes.c */ #include "zutil.c" #include "inftrees.c" #include "infutil.c" #include "infcodes.c" #include "infblock.c" #include "inflate.c" #include "adler32.c" #endif /* !FT_CONFIG_OPTION_SYSTEM_ZLIB */ /***************************************************************************/ /***************************************************************************/ /***** *****/ /***** Z L I B M E M O R Y M A N A G E M E N T *****/ /***** *****/ /***************************************************************************/ /***************************************************************************/ /* it is better to use FreeType memory routines instead of raw 'malloc/free' */ static voidpf ft_gzip_alloc( FT_Memory memory, uInt items, uInt size ) { FT_ULong sz = (FT_ULong)size * items; FT_Pointer p; FT_MEM_ALLOC( p, sz ); return (voidpf) p; } static void ft_gzip_free( FT_Memory memory, voidpf address ) { FT_MEM_FREE( address ); } #ifndef FT_CONFIG_OPTION_SYSTEM_ZLIB local voidpf zcalloc ( voidpf opaque, unsigned items, unsigned size ) { return ft_gzip_alloc( (FT_Memory)opaque, items, size ); } local void zcfree( voidpf opaque, voidpf ptr ) { ft_gzip_free( (FT_Memory)opaque, ptr ); } #endif /* !SYSTEM_ZLIB */ /***************************************************************************/ /***************************************************************************/ /***** *****/ /***** Z L I B F I L E D E S C R I P T O R *****/ /***** *****/ /***************************************************************************/ /***************************************************************************/ #define FT_GZIP_BUFFER_SIZE 4096 typedef struct FT_GZipFileRec_ { FT_Stream source; /* parent/source stream */ FT_Stream stream; /* embedding stream */ FT_Memory memory; /* memory allocator */ z_stream zstream; /* zlib input stream */ FT_ULong start; /* starting position, after .gz header */ FT_Byte input[FT_GZIP_BUFFER_SIZE]; /* input read buffer */ FT_Byte buffer[FT_GZIP_BUFFER_SIZE]; /* output buffer */ FT_ULong pos; /* position in output */ FT_Byte* cursor; FT_Byte* limit; } FT_GZipFileRec, *FT_GZipFile; /* gzip flag byte */ #define FT_GZIP_ASCII_FLAG 0x01 /* bit 0 set: file probably ascii text */ #define FT_GZIP_HEAD_CRC 0x02 /* bit 1 set: header CRC present */ #define FT_GZIP_EXTRA_FIELD 0x04 /* bit 2 set: extra field present */ #define FT_GZIP_ORIG_NAME 0x08 /* bit 3 set: original file name present */ #define FT_GZIP_COMMENT 0x10 /* bit 4 set: file comment present */ #define FT_GZIP_RESERVED 0xE0 /* bits 5..7: reserved */ /* check and skip .gz header - we don't support `transparent' compression */ static FT_Error ft_gzip_check_header( FT_Stream stream ) { FT_Error error; FT_Byte head[4]; if ( FT_STREAM_SEEK( 0 ) || FT_STREAM_READ( head, 4 ) ) goto Exit; /* head[0] && head[1] are the magic numbers; */ /* head[2] is the method, and head[3] the flags */ if ( head[0] != 0x1f || head[1] != 0x8b || head[2] != Z_DEFLATED || (head[3] & FT_GZIP_RESERVED) ) { error = Gzip_Err_Invalid_File_Format; goto Exit; } /* skip time, xflags and os code */ (void)FT_STREAM_SKIP( 6 ); /* skip the extra field */ if ( head[3] & FT_GZIP_EXTRA_FIELD ) { FT_UInt len; if ( FT_READ_USHORT_LE( len ) || FT_STREAM_SKIP( len ) ) goto Exit; } /* skip original file name */ if ( head[3] & FT_GZIP_ORIG_NAME ) for (;;) { FT_UInt c; if ( FT_READ_BYTE( c ) ) goto Exit; if ( c == 0 ) break; } /* skip .gz comment */ if ( head[3] & FT_GZIP_COMMENT ) for (;;) { FT_UInt c; if ( FT_READ_BYTE( c ) ) goto Exit; if ( c == 0 ) break; } /* skip CRC */ if ( head[3] & FT_GZIP_HEAD_CRC ) if ( FT_STREAM_SKIP( 2 ) ) goto Exit; Exit: return error; } static FT_Error ft_gzip_file_init( FT_GZipFile zip, FT_Stream stream, FT_Stream source ) { z_stream* zstream = &zip->zstream; FT_Error error = Gzip_Err_Ok; zip->stream = stream; zip->source = source; zip->memory = stream->memory; zip->limit = zip->buffer + FT_GZIP_BUFFER_SIZE; zip->cursor = zip->limit; zip->pos = 0; /* check and skip .gz header */ { stream = source; error = ft_gzip_check_header( stream ); if ( error ) goto Exit; zip->start = FT_STREAM_POS(); } /* initialize zlib -- there is no zlib header in the compressed stream */ zstream->zalloc = (alloc_func)ft_gzip_alloc; zstream->zfree = (free_func) ft_gzip_free; zstream->opaque = stream->memory; zstream->avail_in = 0; zstream->next_in = zip->buffer; if ( inflateInit2( zstream, -MAX_WBITS ) != Z_OK || zstream->next_in == NULL ) error = Gzip_Err_Invalid_File_Format; Exit: return error; } static void ft_gzip_file_done( FT_GZipFile zip ) { z_stream* zstream = &zip->zstream; inflateEnd( zstream ); /* clear the rest */ zstream->zalloc = NULL; zstream->zfree = NULL; zstream->opaque = NULL; zstream->next_in = NULL; zstream->next_out = NULL; zstream->avail_in = 0; zstream->avail_out = 0; zip->memory = NULL; zip->source = NULL; zip->stream = NULL; } static FT_Error ft_gzip_file_reset( FT_GZipFile zip ) { FT_Stream stream = zip->source; FT_Error error; if ( !FT_STREAM_SEEK( zip->start ) ) { z_stream* zstream = &zip->zstream; inflateReset( zstream ); zstream->avail_in = 0; zstream->next_in = zip->input; zstream->avail_out = 0; zstream->next_out = zip->buffer; zip->limit = zip->buffer + FT_GZIP_BUFFER_SIZE; zip->cursor = zip->limit; zip->pos = 0; } return error; } static FT_Error ft_gzip_file_fill_input( FT_GZipFile zip ) { z_stream* zstream = &zip->zstream; FT_Stream stream = zip->source; FT_ULong size; if ( stream->read ) { size = stream->read( stream, stream->pos, zip->input, FT_GZIP_BUFFER_SIZE ); if ( size == 0 ) return Gzip_Err_Invalid_Stream_Operation; } else { size = stream->size - stream->pos; if ( size > FT_GZIP_BUFFER_SIZE ) size = FT_GZIP_BUFFER_SIZE; if ( size == 0 ) return Gzip_Err_Invalid_Stream_Operation; FT_MEM_COPY( zip->input, stream->base + stream->pos, size ); } stream->pos += size; zstream->next_in = zip->input; zstream->avail_in = size; return Gzip_Err_Ok; } static FT_Error ft_gzip_file_fill_output( FT_GZipFile zip ) { z_stream* zstream = &zip->zstream; FT_Error error = 0; zip->cursor = zip->buffer; zstream->next_out = zip->cursor; zstream->avail_out = FT_GZIP_BUFFER_SIZE; while ( zstream->avail_out > 0 ) { int err; if ( zstream->avail_in == 0 ) { error = ft_gzip_file_fill_input( zip ); if ( error ) break; } err = inflate( zstream, Z_NO_FLUSH ); if ( err == Z_STREAM_END ) { zip->limit = zstream->next_out; if ( zip->limit == zip->cursor ) error = Gzip_Err_Invalid_Stream_Operation; break; } else if ( err != Z_OK ) { error = Gzip_Err_Invalid_Stream_Operation; break; } } return error; } /* fill output buffer; `count' must be <= FT_GZIP_BUFFER_SIZE */ static FT_Error ft_gzip_file_skip_output( FT_GZipFile zip, FT_ULong count ) { FT_Error error = Gzip_Err_Ok; FT_ULong delta; for (;;) { delta = (FT_ULong)( zip->limit - zip->cursor ); if ( delta >= count ) delta = count; zip->cursor += delta; zip->pos += delta; count -= delta; if ( count == 0 ) break; error = ft_gzip_file_fill_output( zip ); if ( error ) break; } return error; } static FT_ULong ft_gzip_file_io( FT_GZipFile zip, FT_ULong pos, FT_Byte* buffer, FT_ULong count ) { FT_ULong result = 0; FT_Error error; /* Reset inflate stream if we're seeking backwards. */ /* Yes, that is not too efficient, but it saves memory :-) */ if ( pos < zip->pos ) { error = ft_gzip_file_reset( zip ); if ( error ) goto Exit; } /* skip unwanted bytes */ if ( pos > zip->pos ) { error = ft_gzip_file_skip_output( zip, (FT_ULong)( pos - zip->pos ) ); if ( error ) goto Exit; } if ( count == 0 ) goto Exit; /* now read the data */ for (;;) { FT_ULong delta; delta = (FT_ULong)( zip->limit - zip->cursor ); if ( delta >= count ) delta = count; FT_MEM_COPY( buffer, zip->cursor, delta ); buffer += delta; result += delta; zip->cursor += delta; zip->pos += delta; count -= delta; if ( count == 0 ) break; error = ft_gzip_file_fill_output( zip ); if ( error ) break; } Exit: return result; } /***************************************************************************/ /***************************************************************************/ /***** *****/ /***** G Z E M B E D D I N G S T R E A M *****/ /***** *****/ /***************************************************************************/ /***************************************************************************/ static void ft_gzip_stream_close( FT_Stream stream ) { FT_GZipFile zip = (FT_GZipFile)stream->descriptor.pointer; FT_Memory memory = stream->memory; if ( zip ) { /* finalize gzip file descriptor */ ft_gzip_file_done( zip ); FT_FREE( zip ); stream->descriptor.pointer = NULL; } } static FT_ULong ft_gzip_stream_io( FT_Stream stream, FT_ULong pos, FT_Byte* buffer, FT_ULong count ) { FT_GZipFile zip = (FT_GZipFile)stream->descriptor.pointer; return ft_gzip_file_io( zip, pos, buffer, count ); } FT_EXPORT_DEF( FT_Error ) FT_Stream_OpenGzip( FT_Stream stream, FT_Stream source ) { FT_Error error; FT_Memory memory = source->memory; FT_GZipFile zip; /* * check the header right now; this prevents allocating un-necessary * objects when we don't need them */ error = ft_gzip_check_header( source ); if ( error ) goto Exit; FT_ZERO( stream ); stream->memory = memory; if ( !FT_QNEW( zip ) ) { error = ft_gzip_file_init( zip, stream, source ); if ( error ) { FT_FREE( zip ); goto Exit; } stream->descriptor.pointer = zip; } stream->size = 0x7FFFFFFFL; /* don't know the real size! */ stream->pos = 0; stream->ba... [truncated message content] |
|
From: Ehud S. <esh...@us...> - 2006-04-21 16:22:37
|
Update of /cvsroot/roadmap/roadmap_editor/src/freetype/src/pfr In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv22848/src/pfr Added Files: pfr.c pfrcmap.c pfrdrivr.c pfrgload.c pfrload.c pfrobjs.c pfrsbit.c Log Message: Import freetype sources. --- NEW FILE: pfrdrivr.c --- /***************************************************************************/ /* */ /* pfrdrivr.c */ /* */ /* FreeType PFR driver interface (body). */ /* */ /* Copyright 2002, 2003, 2004 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_SERVICE_PFR_H #include FT_SERVICE_XFREE86_NAME_H #include "pfrdrivr.h" #include "pfrobjs.h" #include "pfrerror.h" FT_CALLBACK_DEF( FT_Error ) pfr_get_kerning( FT_Face pfrface, /* PFR_Face */ FT_UInt left, FT_UInt right, FT_Vector *avector ) { PFR_Face face = (PFR_Face)pfrface; PFR_PhyFont phys = &face->phy_font; pfr_face_get_kerning( pfrface, left, right, avector ); /* convert from metrics to outline units when necessary */ if ( phys->outline_resolution != phys->metrics_resolution ) { if ( avector->x != 0 ) avector->x = FT_MulDiv( avector->x, phys->outline_resolution, phys->metrics_resolution ); if ( avector->y != 0 ) avector->y = FT_MulDiv( avector->x, phys->outline_resolution, phys->metrics_resolution ); } return PFR_Err_Ok; } /* * PFR METRICS SERVICE * */ FT_CALLBACK_DEF( FT_Error ) pfr_get_advance( FT_Face pfrface, /* PFR_Face */ FT_UInt gindex, FT_Pos *anadvance ) { PFR_Face face = (PFR_Face)pfrface; FT_Error error = PFR_Err_Bad_Argument; *anadvance = 0; if ( face ) { PFR_PhyFont phys = &face->phy_font; if ( gindex < phys->num_chars ) { *anadvance = phys->chars[gindex].advance; error = 0; } } return error; } FT_CALLBACK_DEF( FT_Error ) pfr_get_metrics( FT_Face pfrface, /* PFR_Face */ FT_UInt *anoutline_resolution, FT_UInt *ametrics_resolution, FT_Fixed *ametrics_x_scale, FT_Fixed *ametrics_y_scale ) { PFR_Face face = (PFR_Face)pfrface; PFR_PhyFont phys = &face->phy_font; FT_Fixed x_scale, y_scale; FT_Size size = face->root.size; if ( anoutline_resolution ) *anoutline_resolution = phys->outline_resolution; if ( ametrics_resolution ) *ametrics_resolution = phys->metrics_resolution; x_scale = 0x10000L; y_scale = 0x10000L; if ( size ) { x_scale = FT_DivFix( size->metrics.x_ppem << 6, phys->metrics_resolution ); y_scale = FT_DivFix( size->metrics.y_ppem << 6, phys->metrics_resolution ); } if ( ametrics_x_scale ) *ametrics_x_scale = x_scale; if ( ametrics_y_scale ) *ametrics_y_scale = y_scale; return PFR_Err_Ok; } FT_CALLBACK_TABLE_DEF const FT_Service_PfrMetricsRec pfr_metrics_service_rec = { pfr_get_metrics, pfr_face_get_kerning, pfr_get_advance }; /* * SERVICE LIST * */ static const FT_ServiceDescRec pfr_services[] = { { FT_SERVICE_ID_PFR_METRICS, &pfr_metrics_service_rec }, { FT_SERVICE_ID_XF86_NAME, FT_XF86_FORMAT_PFR }, { NULL, NULL } }; FT_CALLBACK_DEF( FT_Module_Interface ) pfr_get_service( FT_Module module, const FT_String* service_id ) { FT_UNUSED( module ); return ft_service_list_lookup( pfr_services, service_id ); } FT_CALLBACK_TABLE_DEF const FT_Driver_ClassRec pfr_driver_class = { { FT_MODULE_FONT_DRIVER | FT_MODULE_DRIVER_SCALABLE, sizeof( FT_DriverRec ), "pfr", 0x10000L, 0x20000L, NULL, 0, 0, pfr_get_service }, sizeof( PFR_FaceRec ), sizeof( PFR_SizeRec ), sizeof( PFR_SlotRec ), pfr_face_init, pfr_face_done, 0, /* FT_Size_InitFunc */ 0, /* FT_Size_DoneFunc */ pfr_slot_init, pfr_slot_done, 0, /* FT_Size_ResetPointsFunc */ 0, /* FT_Size_ResetPixelsFunc */ pfr_slot_load, pfr_get_kerning, 0, /* FT_Face_AttachFunc */ 0 /* FT_Face_GetAdvancesFunc */ }; /* END */ --- NEW FILE: pfr.c --- /***************************************************************************/ /* */ /* pfr.c */ /* */ /* FreeType PFR driver component. */ /* */ /* Copyright 2002 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. */ /* */ /***************************************************************************/ #define FT_MAKE_OPTION_SINGLE_OBJECT #include <ft2build.h> #include "pfrload.c" #include "pfrgload.c" #include "pfrcmap.c" #include "pfrobjs.c" #include "pfrdrivr.c" #include "pfrsbit.c" /* END */ --- NEW FILE: pfrgload.c --- /***************************************************************************/ /* */ /* pfrgload.c */ /* */ /* FreeType PFR glyph loader (body). */ /* */ /* Copyright 2002, 2003 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 "pfrgload.h" #include "pfrsbit.h" #include "pfrload.h" /* for macro definitions */ #include FT_INTERNAL_DEBUG_H #include "pfrerror.h" #undef FT_COMPONENT #define FT_COMPONENT trace_pfr /*************************************************************************/ /*************************************************************************/ /***** *****/ /***** PFR GLYPH BUILDER *****/ /***** *****/ /*************************************************************************/ /*************************************************************************/ FT_LOCAL_DEF( void ) pfr_glyph_init( PFR_Glyph glyph, FT_GlyphLoader loader ) { FT_ZERO( glyph ); glyph->loader = loader; glyph->path_begun = 0; FT_GlyphLoader_Rewind( loader ); } FT_LOCAL_DEF( void ) pfr_glyph_done( PFR_Glyph glyph ) { FT_Memory memory = glyph->loader->memory; FT_FREE( glyph->x_control ); glyph->y_control = NULL; glyph->max_xy_control = 0; glyph->num_x_control = 0; glyph->num_y_control = 0; FT_FREE( glyph->subs ); glyph->max_subs = 0; glyph->num_subs = 0; glyph->loader = NULL; glyph->path_begun = 0; } /* close current contour, if any */ static void pfr_glyph_close_contour( PFR_Glyph glyph ) { FT_GlyphLoader loader = glyph->loader; FT_Outline* outline = &loader->current.outline; FT_Int last, first; if ( !glyph->path_begun ) return; /* compute first and last point indices in current glyph outline */ last = outline->n_points - 1; first = 0; if ( outline->n_contours > 0 ) first = outline->contours[outline->n_contours - 1]; /* if the last point falls on the same location than the first one */ /* we need to delete it */ if ( last > first ) { FT_Vector* p1 = outline->points + first; FT_Vector* p2 = outline->points + last; if ( p1->x == p2->x && p1->y == p2->y ) { outline->n_points--; last--; } } /* don't add empty contours */ if ( last >= first ) outline->contours[outline->n_contours++] = (short)last; glyph->path_begun = 0; } /* reset glyph to start the loading of a new glyph */ static void pfr_glyph_start( PFR_Glyph glyph ) { glyph->path_begun = 0; } static FT_Error pfr_glyph_line_to( PFR_Glyph glyph, FT_Vector* to ) { FT_GlyphLoader loader = glyph->loader; FT_Outline* outline = &loader->current.outline; FT_Error error; /* check that we have begun a new path */ FT_ASSERT( glyph->path_begun != 0 ); error = FT_GlyphLoader_CheckPoints( loader, 1, 0 ); if ( !error ) { FT_UInt n = outline->n_points; outline->points[n] = *to; outline->tags [n] = FT_CURVE_TAG_ON; outline->n_points++; } return error; } static FT_Error pfr_glyph_curve_to( PFR_Glyph glyph, FT_Vector* control1, FT_Vector* control2, FT_Vector* to ) { FT_GlyphLoader loader = glyph->loader; FT_Outline* outline = &loader->current.outline; FT_Error error; /* check that we have begun a new path */ FT_ASSERT( glyph->path_begun != 0 ); error = FT_GlyphLoader_CheckPoints( loader, 3, 0 ); if ( !error ) { FT_Vector* vec = outline->points + outline->n_points; FT_Byte* tag = (FT_Byte*)outline->tags + outline->n_points; vec[0] = *control1; vec[1] = *control2; vec[2] = *to; tag[0] = FT_CURVE_TAG_CUBIC; tag[1] = FT_CURVE_TAG_CUBIC; tag[2] = FT_CURVE_TAG_ON; outline->n_points = (FT_Short)( outline->n_points + 3 ); } return error; } static FT_Error pfr_glyph_move_to( PFR_Glyph glyph, FT_Vector* to ) { FT_GlyphLoader loader = glyph->loader; FT_Error error; /* close current contour if any */ pfr_glyph_close_contour( glyph ); /* indicate that a new contour has started */ glyph->path_begun = 1; /* check that there is space for a new contour and a new point */ error = FT_GlyphLoader_CheckPoints( loader, 1, 1 ); if ( !error ) /* add new start point */ error = pfr_glyph_line_to( glyph, to ); return error; } static void pfr_glyph_end( PFR_Glyph glyph ) { /* close current contour if any */ pfr_glyph_close_contour( glyph ); /* merge the current glyph into the stack */ FT_GlyphLoader_Add( glyph->loader ); } /*************************************************************************/ /*************************************************************************/ /***** *****/ /***** PFR GLYPH LOADER *****/ /***** *****/ /*************************************************************************/ /*************************************************************************/ /* load a simple glyph */ static FT_Error pfr_glyph_load_simple( PFR_Glyph glyph, FT_Byte* p, FT_Byte* limit ) { FT_Error error = 0; FT_Memory memory = glyph->loader->memory; FT_UInt flags, x_count, y_count, i, count, mask; FT_Int x; PFR_CHECK( 1 ); flags = PFR_NEXT_BYTE( p ); /* test for composite glyphs */ FT_ASSERT( ( flags & PFR_GLYPH_IS_COMPOUND ) == 0 ); x_count = 0; y_count = 0; if ( flags & PFR_GLYPH_1BYTE_XYCOUNT ) { PFR_CHECK( 1 ); count = PFR_NEXT_BYTE( p ); x_count = ( count & 15 ); y_count = ( count >> 4 ); } else { if ( flags & PFR_GLYPH_XCOUNT ) { PFR_CHECK( 1 ); x_count = PFR_NEXT_BYTE( p ); } if ( flags & PFR_GLYPH_YCOUNT ) { PFR_CHECK( 1 ); y_count = PFR_NEXT_BYTE( p ); } } count = x_count + y_count; /* re-allocate array when necessary */ if ( count > glyph->max_xy_control ) { FT_UInt new_max = FT_PAD_CEIL( count, 8 ); if ( FT_RENEW_ARRAY( glyph->x_control, glyph->max_xy_control, new_max ) ) goto Exit; glyph->max_xy_control = new_max; } glyph->y_control = glyph->x_control + x_count; mask = 0; x = 0; for ( i = 0; i < count; i++ ) { if ( ( i & 7 ) == 0 ) { PFR_CHECK( 1 ); mask = PFR_NEXT_BYTE( p ); } if ( mask & 1 ) { PFR_CHECK( 2 ); x = PFR_NEXT_SHORT( p ); } else { PFR_CHECK( 1 ); x += PFR_NEXT_BYTE( p ); } glyph->x_control[i] = x; mask >>= 1; } /* XXX: for now we ignore the secondary stroke and edge definitions */ /* since we don't want to support native PFR hinting */ /* */ if ( flags & PFR_GLYPH_EXTRA_ITEMS ) { error = pfr_extra_items_skip( &p, limit ); if ( error ) goto Exit; } pfr_glyph_start( glyph ); /* now load a simple glyph */ { FT_Vector pos[4]; FT_Vector* cur; pos[0].x = pos[0].y = 0; pos[3] = pos[0]; for (;;) { FT_Int format, args_format = 0, args_count, n; /***************************************************************/ /* read instruction */ /* */ PFR_CHECK( 1 ); format = PFR_NEXT_BYTE( p ); switch ( format >> 4 ) { case 0: /* end glyph */ FT_TRACE6(( "- end glyph" )); args_count = 0; break; case 1: /* general line operation */ FT_TRACE6(( "- general line" )); goto Line1; case 4: /* move to inside contour */ FT_TRACE6(( "- move to inside" )); goto Line1; case 5: /* move to outside contour */ FT_TRACE6(( "- move to outside" )); Line1: args_format = format & 15; args_count = 1; break; case 2: /* horizontal line to */ FT_TRACE6(( "- horizontal line to cx.%d", format & 15 )); pos[0].y = pos[3].y; pos[0].x = glyph->x_control[format & 15]; pos[3] = pos[0]; args_count = 0; break; case 3: /* vertical line to */ FT_TRACE6(( "- vertical line to cy.%d", format & 15 )); pos[0].x = pos[3].x; pos[0].y = glyph->y_control[format & 15]; pos[3] = pos[0]; args_count = 0; break; case 6: /* horizontal to vertical curve */ FT_TRACE6(( "- hv curve " )); args_format = 0xB8E; args_count = 3; break; case 7: /* vertical to horizontal curve */ FT_TRACE6(( "- vh curve" )); args_format = 0xE2B; args_count = 3; break; default: /* general curve to */ FT_TRACE6(( "- general curve" )); args_count = 4; args_format = format & 15; } /***********************************************************/ /* now read arguments */ /* */ cur = pos; for ( n = 0; n < args_count; n++ ) { FT_Int idx, delta; /* read the X argument */ switch ( args_format & 3 ) { case 0: /* 8-bit index */ PFR_CHECK( 1 ); idx = PFR_NEXT_BYTE( p ); cur->x = glyph->x_control[idx]; FT_TRACE7(( " cx#%d", idx )); break; case 1: /* 16-bit value */ PFR_CHECK( 2 ); cur->x = PFR_NEXT_SHORT( p ); FT_TRACE7(( " x.%d", cur->x )); break; case 2: /* 8-bit delta */ PFR_CHECK( 1 ); delta = PFR_NEXT_INT8( p ); cur->x = pos[3].x + delta; FT_TRACE7(( " dx.%d", delta )); break; default: FT_TRACE7(( " |" )); cur->x = pos[3].x; } /* read the Y argument */ switch ( ( args_format >> 2 ) & 3 ) { case 0: /* 8-bit index */ PFR_CHECK( 1 ); idx = PFR_NEXT_BYTE( p ); cur->y = glyph->y_control[idx]; FT_TRACE7(( " cy#%d", idx )); break; case 1: /* 16-bit absolute value */ PFR_CHECK( 2 ); cur->y = PFR_NEXT_SHORT( p ); FT_TRACE7(( " y.%d", cur->y )); break; case 2: /* 8-bit delta */ PFR_CHECK( 1 ); delta = PFR_NEXT_INT8( p ); cur->y = pos[3].y + delta; FT_TRACE7(( " dy.%d", delta )); break; default: FT_TRACE7(( " -" )); cur->y = pos[3].y; } /* read the additional format flag for the general curve */ if ( n == 0 && args_count == 4 ) { PFR_CHECK( 1 ); args_format = PFR_NEXT_BYTE( p ); args_count--; } else args_format >>= 4; /* save the previous point */ pos[3] = cur[0]; cur++; } FT_TRACE7(( "\n" )); /***********************************************************/ /* finally, execute instruction */ /* */ switch ( format >> 4 ) { case 0: /* end glyph => EXIT */ pfr_glyph_end( glyph ); goto Exit; case 1: /* line operations */ case 2: case 3: error = pfr_glyph_line_to( glyph, pos ); goto Test_Error; case 4: /* move to inside contour */ case 5: /* move to outside contour */ error = pfr_glyph_move_to( glyph, pos ); goto Test_Error; default: /* curve operations */ error = pfr_glyph_curve_to( glyph, pos, pos + 1, pos + 2 ); Test_Error: /* test error condition */ if ( error ) goto Exit; } } /* for (;;) */ } Exit: return error; Too_Short: error = PFR_Err_Invalid_Table; FT_ERROR(( "pfr_glyph_load_simple: invalid glyph data\n" )); goto Exit; } /* load a composite/compound glyph */ static FT_Error pfr_glyph_load_compound( PFR_Glyph glyph, FT_Byte* p, FT_Byte* limit ) { FT_Error error = 0; FT_GlyphLoader loader = glyph->loader; FT_Memory memory = loader->memory; PFR_SubGlyph subglyph; FT_UInt flags, i, count, org_count; FT_Int x_pos, y_pos; PFR_CHECK( 1 ); flags = PFR_NEXT_BYTE( p ); /* test for composite glyphs */ FT_ASSERT( ( flags & PFR_GLYPH_IS_COMPOUND ) != 0 ); count = flags & 0x3F; /* ignore extra items when present */ /* */ if ( flags & PFR_GLYPH_EXTRA_ITEMS ) { error = pfr_extra_items_skip( &p, limit ); if (error) goto Exit; } /* we can't rely on the FT_GlyphLoader to load sub-glyphs, because */ /* the PFR format is dumb, using direct file offsets to point to the */ /* sub-glyphs (instead of glyph indices). Sigh. */ /* */ /* For now, we load the list of sub-glyphs into a different array */ /* but this will prevent us from using the auto-hinter at its best */ /* quality. */ /* */ org_count = glyph->num_subs; if ( org_count + count > glyph->max_subs ) { FT_UInt new_max = ( org_count + count + 3 ) & -4; if ( FT_RENEW_ARRAY( glyph->subs, glyph->max_subs, new_max ) ) goto Exit; glyph->max_subs = new_max; } subglyph = glyph->subs + org_count; for ( i = 0; i < count; i++, subglyph++ ) { FT_UInt format; x_pos = 0; y_pos = 0; PFR_CHECK( 1 ); format = PFR_NEXT_BYTE( p ); /* read scale when available */ subglyph->x_scale = 0x10000L; if ( format & PFR_SUBGLYPH_XSCALE ) { PFR_CHECK( 2 ); subglyph->x_scale = PFR_NEXT_SHORT( p ) << 4; } subglyph->y_scale = 0x10000L; if ( format & PFR_SUBGLYPH_YSCALE ) { PFR_CHECK( 2 ); subglyph->y_scale = PFR_NEXT_SHORT( p ) << 4; } /* read offset */ switch ( format & 3 ) { case 1: PFR_CHECK( 2 ); x_pos = PFR_NEXT_SHORT( p ); break; case 2: PFR_CHECK( 1 ); x_pos += PFR_NEXT_INT8( p ); break; default: ; } switch ( ( format >> 2 ) & 3 ) { case 1: PFR_CHECK( 2 ); y_pos = PFR_NEXT_SHORT( p ); break; case 2: PFR_CHECK( 1 ); y_pos += PFR_NEXT_INT8( p ); break; default: ; } subglyph->x_delta = x_pos; subglyph->y_delta = y_pos; /* read glyph position and size now */ if ( format & PFR_SUBGLYPH_2BYTE_SIZE ) { PFR_CHECK( 2 ); subglyph->gps_size = PFR_NEXT_USHORT( p ); } else { PFR_CHECK( 1 ); subglyph->gps_size = PFR_NEXT_BYTE( p ); } if ( format & PFR_SUBGLYPH_3BYTE_OFFSET ) { PFR_CHECK( 3 ); subglyph->gps_offset = PFR_NEXT_LONG( p ); } else { PFR_CHECK( 2 ); subglyph->gps_offset = PFR_NEXT_USHORT( p ); } glyph->num_subs++; } Exit: return error; Too_Short: error = PFR_Err_Invalid_Table; FT_ERROR(( "pfr_glyph_load_compound: invalid glyph data\n" )); goto Exit; } static FT_Error pfr_glyph_load_rec( PFR_Glyph glyph, FT_Stream stream, FT_ULong gps_offset, FT_ULong offset, FT_ULong size ) { FT_Error error; FT_Byte* p; FT_Byte* limit; if ( FT_STREAM_SEEK( gps_offset + offset ) || FT_FRAME_ENTER( size ) ) goto Exit; p = (FT_Byte*)stream->cursor; limit = p + size; if ( size > 0 && *p & PFR_GLYPH_IS_COMPOUND ) { FT_Int n, old_count, count; FT_GlyphLoader loader = glyph->loader; FT_Outline* base = &loader->base.outline; old_count = glyph->num_subs; /* this is a compound glyph - load it */ error = pfr_glyph_load_compound( glyph, p, limit ); FT_FRAME_EXIT(); if ( error ) goto Exit; count = glyph->num_subs - old_count; /* now, load each individual glyph */ for ( n = 0; n < count; n++ ) { FT_Int i, old_points, num_points; PFR_SubGlyph subglyph; subglyph = glyph->subs + old_count + n; old_points = base->n_points; error = pfr_glyph_load_rec( glyph, stream, gps_offset, subglyph->gps_offset, subglyph->gps_size ); if ( error ) goto Exit; /* note that `glyph->subs' might have been re-allocated */ subglyph = glyph->subs + old_count + n; num_points = base->n_points - old_points; /* translate and eventually scale the new glyph points */ if ( subglyph->x_scale != 0x10000L || subglyph->y_scale != 0x10000L ) { FT_Vector* vec = base->points + old_points; for ( i = 0; i < num_points; i++, vec++ ) { vec->x = FT_MulFix( vec->x, subglyph->x_scale ) + subglyph->x_delta; vec->y = FT_MulFix( vec->y, subglyph->y_scale ) + subglyph->y_delta; } } else { FT_Vector* vec = loader->base.outline.points + old_points; for ( i = 0; i < num_points; i++, vec++ ) { vec->x += subglyph->x_delta; vec->y += subglyph->y_delta; } } /* proceed to next sub-glyph */ } } else { /* load a simple glyph */ error = pfr_glyph_load_simple( glyph, p, limit ); FT_FRAME_EXIT(); } Exit: return error; } FT_LOCAL_DEF( FT_Error ) pfr_glyph_load( PFR_Glyph glyph, FT_Stream stream, FT_ULong gps_offset, FT_ULong offset, FT_ULong size ) { /* initialize glyph loader */ FT_GlyphLoader_Rewind( glyph->loader ); glyph->num_subs = 0; /* load the glyph, recursively when needed */ return pfr_glyph_load_rec( glyph, stream, gps_offset, offset, size ); } /* END */ --- NEW FILE: pfrobjs.c --- /***************************************************************************/ /* */ /* pfrobjs.c */ /* */ /* FreeType PFR object methods (body). */ /* */ /* Copyright 2002, 2003, 2004, 2005 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 "pfrobjs.h" #include "pfrload.h" #include "pfrgload.h" #include "pfrcmap.h" #include "pfrsbit.h" #include FT_OUTLINE_H #include FT_INTERNAL_DEBUG_H #include "pfrerror.h" #undef FT_COMPONENT #define FT_COMPONENT trace_pfr /*************************************************************************/ /*************************************************************************/ /***** *****/ /***** FACE OBJECT METHODS *****/ /***** *****/ /*************************************************************************/ /*************************************************************************/ FT_LOCAL_DEF( void ) pfr_face_done( FT_Face pfrface ) /* PFR_Face */ { PFR_Face face = (PFR_Face)pfrface; FT_Memory memory = pfrface->driver->root.memory; /* we don't want dangling pointers */ pfrface->family_name = NULL; pfrface->style_name = NULL; /* finalize the physical font record */ pfr_phy_font_done( &face->phy_font, FT_FACE_MEMORY( face ) ); /* no need to finalize the logical font or the header */ FT_FREE( pfrface->available_sizes ); } FT_LOCAL_DEF( FT_Error ) pfr_face_init( FT_Stream stream, FT_Face pfrface, FT_Int face_index, FT_Int num_params, FT_Parameter* params ) { PFR_Face face = (PFR_Face)pfrface; FT_Error error; FT_UNUSED( num_params ); FT_UNUSED( params ); /* load the header and check it */ error = pfr_header_load( &face->header, stream ); if ( error ) goto Exit; if ( !pfr_header_check( &face->header ) ) { FT_TRACE4(( "pfr_face_init: not a valid PFR font\n" )); error = PFR_Err_Unknown_File_Format; goto Exit; } /* check face index */ { FT_UInt num_faces; error = pfr_log_font_count( stream, face->header.log_dir_offset, &num_faces ); if ( error ) goto Exit; pfrface->num_faces = num_faces; } if ( face_index < 0 ) goto Exit; if ( face_index >= pfrface->num_faces ) { FT_ERROR(( "pfr_face_init: invalid face index\n" )); error = PFR_Err_Invalid_Argument; goto Exit; } /* load the face */ error = pfr_log_font_load( &face->log_font, stream, face_index, face->header.log_dir_offset, FT_BOOL( face->header.phy_font_max_size_high != 0 ) ); if ( error ) goto Exit; /* now load the physical font descriptor */ error = pfr_phy_font_load( &face->phy_font, stream, face->log_font.phys_offset, face->log_font.phys_size ); if ( error ) goto Exit; /* now, set-up all root face fields */ { PFR_PhyFont phy_font = &face->phy_font; pfrface->face_index = face_index; pfrface->num_glyphs = phy_font->num_chars; pfrface->face_flags = FT_FACE_FLAG_SCALABLE; if ( (phy_font->flags & PFR_PHY_PROPORTIONAL) == 0 ) pfrface->face_flags |= FT_FACE_FLAG_FIXED_WIDTH; if ( phy_font->flags & PFR_PHY_VERTICAL ) pfrface->face_flags |= FT_FACE_FLAG_VERTICAL; else pfrface->face_flags |= FT_FACE_FLAG_HORIZONTAL; if ( phy_font->num_strikes > 0 ) pfrface->face_flags |= FT_FACE_FLAG_FIXED_SIZES; if ( phy_font->num_kern_pairs > 0 ) pfrface->face_flags |= FT_FACE_FLAG_KERNING; /* If no family name was found in the "undocumented" auxiliary * data, use the font ID instead. This sucks but is better than * nothing. */ pfrface->family_name = phy_font->family_name; if ( pfrface->family_name == NULL ) pfrface->family_name = phy_font->font_id; /* note that the style name can be NULL in certain PFR fonts, * probably meaning "Regular" */ pfrface->style_name = phy_font->style_name; pfrface->num_fixed_sizes = 0; pfrface->available_sizes = 0; pfrface->bbox = phy_font->bbox; pfrface->units_per_EM = (FT_UShort)phy_font->outline_resolution; pfrface->ascender = (FT_Short) phy_font->bbox.yMax; pfrface->descender = (FT_Short) phy_font->bbox.yMin; pfrface->height = (FT_Short)( ( ( pfrface->ascender - pfrface->descender ) * 12 ) / 10 ); if ( phy_font->num_strikes > 0 ) { FT_UInt n, count = phy_font->num_strikes; FT_Bitmap_Size* size; PFR_Strike strike; FT_Memory memory = pfrface->stream->memory; if ( FT_NEW_ARRAY( pfrface->available_sizes, count ) ) goto Exit; size = pfrface->available_sizes; strike = phy_font->strikes; for ( n = 0; n < count; n++, size++, strike++ ) { size->height = (FT_UShort)strike->y_ppm; size->width = (FT_UShort)strike->x_ppm; } pfrface->num_fixed_sizes = count; } /* now compute maximum advance width */ if ( ( phy_font->flags & PFR_PHY_PROPORTIONAL ) == 0 ) pfrface->max_advance_width = (FT_Short)phy_font->standard_advance; else { FT_Int max = 0; FT_UInt count = phy_font->num_chars; PFR_Char gchar = phy_font->chars; for ( ; count > 0; count--, gchar++ ) { if ( max < gchar->advance ) max = gchar->advance; } pfrface->max_advance_width = (FT_Short)max; } pfrface->max_advance_height = pfrface->height; pfrface->underline_position = (FT_Short)( -pfrface->units_per_EM / 10 ); pfrface->underline_thickness = (FT_Short)( pfrface->units_per_EM / 30 ); /* create charmap */ { FT_CharMapRec charmap; charmap.face = pfrface; charmap.platform_id = 3; charmap.encoding_id = 1; charmap.encoding = FT_ENCODING_UNICODE; FT_CMap_New( &pfr_cmap_class_rec, NULL, &charmap, NULL ); #if 0 /* Select default charmap */ if ( pfrface->num_charmaps ) pfrface->charmap = pfrface->charmaps[0]; #endif } /* check whether we've loaded any kerning pairs */ if ( phy_font->num_kern_pairs ) pfrface->face_flags |= FT_FACE_FLAG_KERNING; } Exit: return error; } /*************************************************************************/ /*************************************************************************/ /***** *****/ /***** SLOT OBJECT METHOD *****/ /***** *****/ /*************************************************************************/ /*************************************************************************/ FT_LOCAL_DEF( FT_Error ) pfr_slot_init( FT_GlyphSlot pfrslot ) /* PFR_Slot */ { PFR_Slot slot = (PFR_Slot)pfrslot; FT_GlyphLoader loader = pfrslot->internal->loader; pfr_glyph_init( &slot->glyph, loader ); return 0; } FT_LOCAL_DEF( void ) pfr_slot_done( FT_GlyphSlot pfrslot ) /* PFR_Slot */ { PFR_Slot slot = (PFR_Slot)pfrslot; pfr_glyph_done( &slot->glyph ); } FT_LOCAL_DEF( FT_Error ) pfr_slot_load( FT_GlyphSlot pfrslot, /* PFR_Slot */ FT_Size pfrsize, /* PFR_Size */ FT_UInt gindex, FT_Int32 load_flags ) { PFR_Slot slot = (PFR_Slot)pfrslot; PFR_Size size = (PFR_Size)pfrsize; FT_Error error; PFR_Face face = (PFR_Face)pfrslot->face; PFR_Char gchar; FT_Outline* outline = &pfrslot->outline; FT_ULong gps_offset; if ( gindex > 0 ) gindex--; /* check that the glyph index is correct */ FT_ASSERT( gindex < face->phy_font.num_chars ); /* try to load an embedded bitmap */ if ( ( load_flags & ( FT_LOAD_NO_SCALE | FT_LOAD_NO_BITMAP ) ) == 0 ) { error = pfr_slot_load_bitmap( slot, size, gindex ); if ( error == 0 ) goto Exit; } if ( load_flags & FT_LOAD_SBITS_ONLY ) { error = PFR_Err_Invalid_Argument; goto Exit; } gchar = face->phy_font.chars + gindex; pfrslot->format = FT_GLYPH_FORMAT_OUTLINE; outline->n_points = 0; outline->n_contours = 0; gps_offset = face->header.gps_section_offset; /* load the glyph outline (FT_LOAD_NO_RECURSE isn't supported) */ error = pfr_glyph_load( &slot->glyph, face->root.stream, gps_offset, gchar->gps_offset, gchar->gps_size ); if ( !error ) { FT_BBox cbox; FT_Glyph_Metrics* metrics = &pfrslot->metrics; FT_Pos advance; FT_Int em_metrics, em_outline; FT_Bool scaling; scaling = FT_BOOL( ( load_flags & FT_LOAD_NO_SCALE ) == 0 ); /* copy outline data */ *outline = slot->glyph.loader->base.outline; outline->flags &= ~FT_OUTLINE_OWNER; outline->flags |= FT_OUTLINE_REVERSE_FILL; if ( size && pfrsize->metrics.y_ppem < 24 ) outline->flags |= FT_OUTLINE_HIGH_PRECISION; /* compute the advance vector */ metrics->horiAdvance = 0; metrics->vertAdvance = 0; advance = gchar->advance; em_metrics = face->phy_font.metrics_resolution; em_outline = face->phy_font.outline_resolution; if ( em_metrics != em_outline ) advance = FT_MulDiv( advance, em_outline, em_metrics ); if ( face->phy_font.flags & PFR_PHY_VERTICAL ) metrics->vertAdvance = advance; else metrics->horiAdvance = advance; pfrslot->linearHoriAdvance = metrics->horiAdvance; pfrslot->linearVertAdvance = metrics->vertAdvance; /* make-up vertical metrics(?) */ metrics->vertBearingX = 0; metrics->vertBearingY = 0; #if 0 /* some fonts seem to be broken here! */ /* Apply the font matrix, if any. */ /* TODO: Test existing fonts with unusual matrix */ /* whether we have to adjust Units per EM. */ { FT_Matrix font_matrix; font_matrix.xx = face->log_font.matrix[0] << 8; font_matrix.yx = face->log_font.matrix[1] << 8; font_matrix.xy = face->log_font.matrix[2] << 8; font_matrix.yy = face->log_font.matrix[3] << 8; FT_Outline_Transform( outline, &font_matrix ); } #endif /* scale when needed */ if ( scaling ) { FT_Int n; FT_Fixed x_scale = pfrsize->metrics.x_scale; FT_Fixed y_scale = pfrsize->metrics.y_scale; FT_Vector* vec = outline->points; /* scale outline points */ for ( n = 0; n < outline->n_points; n++, vec++ ) { vec->x = FT_MulFix( vec->x, x_scale ); vec->y = FT_MulFix( vec->y, y_scale ); } /* scale the advance */ metrics->horiAdvance = FT_MulFix( metrics->horiAdvance, x_scale ); metrics->vertAdvance = FT_MulFix( metrics->vertAdvance, y_scale ); } /* compute the rest of the metrics */ FT_Outline_Get_CBox( outline, &cbox ); metrics->width = cbox.xMax - cbox.xMin; metrics->height = cbox.yMax - cbox.yMin; metrics->horiBearingX = cbox.xMin; metrics->horiBearingY = cbox.yMax - metrics->height; } Exit: return error; } /*************************************************************************/ /*************************************************************************/ /***** *****/ /***** KERNING METHOD *****/ /***** *****/ /*************************************************************************/ /*************************************************************************/ #ifdef FT_OPTIMIZE_MEMORY FT_LOCAL_DEF( FT_Error ) pfr_face_get_kerning( FT_Face pfrface, /* PFR_Face */ FT_UInt glyph1, FT_UInt glyph2, FT_Vector* kerning ) { PFR_Face face = (PFR_Face)pfrface; FT_Error error = PFR_Err_Ok; PFR_PhyFont phy_font = &face->phy_font; FT_UInt32 code1, code2, pair; kerning->x = 0; kerning->y = 0; if ( glyph1 > 0 ) glyph1--; if ( glyph2 > 0 ) glyph2--; /* convert glyph indices to character codes */ if ( glyph1 > phy_font->num_chars || glyph2 > phy_font->num_chars ) goto Exit; code1 = phy_font->chars[glyph1].char_code; code2 = phy_font->chars[glyph2].char_code; pair = PFR_KERN_INDEX( code1, code2 ); /* now search the list of kerning items */ { PFR_KernItem item = phy_font->kern_items; FT_Stream stream = pfrface->stream; for ( ; item; item = item->next ) { if ( pair >= item->pair1 && pair <= item->pair2 ) goto FoundPair; } goto Exit; FoundPair: /* we found an item, now parse it and find the value if any */ if ( FT_STREAM_SEEK( item->offset ) || FT_FRAME_ENTER( item->pair_count * item->pair_size ) ) goto Exit; { FT_UInt count = item->pair_count; FT_UInt size = item->pair_size; FT_UInt power = (FT_UInt)ft_highpow2( (FT_UInt32)count ); FT_UInt probe = power * size; FT_UInt extra = count - power; FT_Byte* base = stream->cursor; FT_Bool twobytes = item->flags & 1; FT_Byte* p; FT_UInt32 cpair; if ( extra > 0 ) { p = base + extra * size; if ( twobytes ) cpair = FT_NEXT_ULONG( p ); else cpair = PFR_NEXT_KPAIR( p ); if ( cpair == pair ) goto Found; if ( cpair < pair ) base = p; } while ( probe > size ) { probe >>= 1; p = base + probe; if ( twobytes ) cpair = FT_NEXT_ULONG( p ); else cpair = PFR_NEXT_KPAIR( p ); if ( cpair == pair ) goto Found; if ( cpair < pair ) base += probe; } p = base; if ( twobytes ) cpair = FT_NEXT_ULONG( p ); else cpair = PFR_NEXT_KPAIR( p ); if ( cpair == pair ) { FT_Int value; Found: if ( item->flags & 2 ) value = FT_PEEK_SHORT( p ); else value = p[0]; kerning->x = item->base_adj + value; } } FT_FRAME_EXIT(); } Exit: return error; } #else /* !FT_OPTIMIZE_MEMORY */ FT_LOCAL_DEF( FT_Error ) pfr_face_get_kerning( FT_Face pfrface, /* PFR_Face */ FT_UInt glyph1, FT_UInt glyph2, FT_Vector* kerning ) { PFR_Face face = (PFR_Face)pfrface; FT_Error error = PFR_Err_Ok; PFR_PhyFont phy_font = &face->phy_font; PFR_KernPair pairs = phy_font->kern_pairs; FT_UInt32 idx = PFR_KERN_INDEX( glyph1, glyph2 ); FT_UInt min, max; kerning->x = 0; kerning->y = 0; min = 0; max = phy_font->num_kern_pairs; while ( min < max ) { FT_UInt mid = ( min + max ) >> 1; PFR_KernPair pair = pairs + mid; FT_UInt32 pidx = PFR_KERN_PAIR_INDEX( pair ); if ( pidx == idx ) { kerning->x = pair->kerning; break; } if ( pidx < idx ) min = mid + 1; else max = mid; } return error; } #endif /* !FT_OPTIMIZE_MEMORY */ /* END */ --- NEW FILE: pfrsbit.c --- /***************************************************************************/ /* */ /* pfrsbit.c */ /* */ /* FreeType PFR bitmap loader (body). */ /* */ /* Copyright 2002, 2003 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 "pfrsbit.h" #include "pfrload.h" #include FT_INTERNAL_DEBUG_H #include FT_INTERNAL_STREAM_H #include "pfrerror.h" #undef FT_COMPONENT #define FT_COMPONENT trace_pfr /*************************************************************************/ /*************************************************************************/ /***** *****/ /***** PFR BIT WRITER *****/ /***** *****/ /*************************************************************************/ /*************************************************************************/ typedef struct PFR_BitWriter_ { FT_Byte* line; /* current line start */ FT_Int pitch; /* line size in bytes */ FT_Int width; /* width in pixels/bits */ FT_Int rows; /* number of remaining rows to scan */ FT_Int total; /* total number of bits to draw */ } PFR_BitWriterRec, *PFR_BitWriter; static void pfr_bitwriter_init( PFR_BitWriter writer, FT_Bitmap* target, FT_Bool decreasing ) { writer->line = target->buffer; writer->pitch = target->pitch; writer->width = target->width; writer->rows = target->rows; writer->total = writer->width * writer->rows; if ( !decreasing ) { writer->line += writer->pitch * ( target->rows-1 ); writer->pitch = -writer->pitch; } } static void pfr_bitwriter_decode_bytes( PFR_BitWriter writer, FT_Byte* p, FT_Byte* limit ) { FT_Int n, reload; FT_Int left = writer->width; FT_Byte* cur = writer->line; FT_UInt mask = 0x80; FT_UInt val = 0; FT_UInt c = 0; n = (FT_Int)( limit - p ) * 8; if ( n > writer->total ) n = writer->total; reload = n & 7; for ( ; n > 0; n-- ) { if ( ( n & 7 ) == reload ) val = *p++; if ( val & 0x80 ) c |= mask; val <<= 1; mask >>= 1; if ( --left <= 0 ) { cur[0] = (FT_Byte)c; left = writer->width; mask = 0x80; writer->line += writer->pitch; cur = writer->line; c = 0; } else if ( mask == 0 ) { cur[0] = (FT_Byte)c; mask = 0x80; c = 0; cur ++; } } if ( mask != 0x80 ) cur[0] = (FT_Byte)c; } static void pfr_bitwriter_decode_rle1( PFR_BitWriter writer, FT_Byte* p, FT_Byte* limit ) { FT_Int n, phase, count, counts[2], reload; FT_Int left = writer->width; FT_Byte* cur = writer->line; FT_UInt mask = 0x80; FT_UInt c = 0; n = writer->total; phase = 1; counts[0] = 0; counts[1] = 0; count = 0; reload = 1; for ( ; n > 0; n-- ) { if ( reload ) { do { if ( phase ) { FT_Int v; if ( p >= limit ) break; v = *p++; counts[0] = v >> 4; counts[1] = v & 15; phase = 0; count = counts[0]; } else { phase = 1; count = counts[1]; } } while ( count == 0 ); } if ( phase ) c |= mask; mask >>= 1; if ( --left <= 0 ) { cur[0] = (FT_Byte) c; left = writer->width; mask = 0x80; writer->line += writer->pitch; cur = writer->line; c = 0; } else if ( mask == 0 ) { cur[0] = (FT_Byte)c; mask = 0x80; c = 0; cur ++; } reload = ( --count <= 0 ); } if ( mask != 0x80 ) cur[0] = (FT_Byte) c; } static void pfr_bitwriter_decode_rle2( PFR_BitWriter writer, FT_Byte* p, FT_Byte* limit ) { FT_Int n, phase, count, reload; FT_Int left = writer->width; FT_Byte* cur = writer->line; FT_UInt mask = 0x80; FT_UInt c = 0; n = writer->total; phase = 1; count = 0; reload = 1; for ( ; n > 0; n-- ) { if ( reload ) { do { if ( p >= limit ) break; count = *p++; phase = phase ^ 1; } while ( count == 0 ); } if ( phase ) c |= mask; mask >>= 1; if ( --left <= 0 ) { cur[0] = (FT_Byte) c; c = 0; mask = 0x80; left = writer->width; writer->line += writer->pitch; cur = writer->line; } else if ( mask == 0 ) { cur[0] = (FT_Byte)c; c = 0; mask = 0x80; cur ++; } reload = ( --count <= 0 ); } if ( mask != 0x80 ) cur[0] = (FT_Byte) c; } /*************************************************************************/ /*************************************************************************/ /***** *****/ /***** BITMAP DATA DECODING *****/ /***** *****/ /*************************************************************************/ /*************************************************************************/ static void pfr_lookup_bitmap_data( FT_Byte* base, FT_Byte* limit, FT_UInt count, FT_UInt flags, FT_UInt char_code, FT_ULong* found_offset, FT_ULong* found_size ) { FT_UInt left, right, char_len; FT_Bool two = FT_BOOL( flags & 1 ); FT_Byte* buff; char_len = 4; if ( two ) char_len += 1; if ( flags & 2 ) char_len += 1; if ( flags & 4 ) char_len += 1; left = 0; right = count; while ( left < right ) { FT_UInt middle, code; middle = ( left + right ) >> 1; buff = base + middle * char_len; /* check that we are not outside of the table -- */ /* this is possible with broken fonts... */ if ( buff + char_len > limit ) goto Fail; if ( two ) code = PFR_NEXT_USHORT( buff ); else code = PFR_NEXT_BYTE( buff ); if ( code == char_code ) goto Found_It; if ( code < char_code ) left = middle; else right = middle; } Fail: /* Not found */ *found_size = 0; *found_offset = 0; return; Found_It: if ( flags & 2 ) *found_size = PFR_NEXT_USHORT( buff ); else *found_size = PFR_NEXT_BYTE( buff ); if ( flags & 4 ) *found_offset = PFR_NEXT_ULONG( buff ); else *found_offset = PFR_NEXT_USHORT( buff ); } /* load bitmap metrics. "*padvance" must be set to the default value */ /* before calling this function... */ /* */ static FT_Error pfr_load_bitmap_metrics( FT_Byte** pdata, FT_Byte* limit, FT_Long scaled_advance, FT_Long *axpos, FT_Long *aypos, FT_UInt *axsize, FT_UInt *aysize, FT_Long *aadvance, FT_UInt *aformat ) { FT_Error error = 0; FT_Byte flags; FT_Char b; FT_Byte* p = *pdata; FT_Long xpos, ypos, advance; FT_UInt xsize, ysize; PFR_CHECK( 1 ); flags = PFR_NEXT_BYTE( p ); xpos = 0; ypos = 0; xsize = 0; ysize = 0; advance = 0; switch ( flags & 3 ) { case 0: PFR_CHECK( 1 ); b = PFR_NEXT_INT8( p ); xpos = b >> 4; ypos = ( (FT_Char)( b << 4 ) ) >> 4; break; case 1: PFR_CHECK( 2 ); xpos = PFR_NEXT_INT8( p ); ypos = PFR_NEXT_INT8( p ); break; case 2: PFR_CHECK( 4 ); xpos = PFR_NEXT_SHORT( p ); ypos = PFR_NEXT_SHORT( p ); break; case 3: PFR_CHECK( 6 ); xpos = PFR_NEXT_LONG( p ); ypos = PFR_NEXT_LONG( p ); break; default: ; } flags >>= 2; switch ( flags & 3 ) { case 0: /* blank image */ xsize = 0; ysize = 0; break; case 1: PFR_CHECK( 1 ); b = PFR_NEXT_BYTE( p ); xsize = ( b >> 4 ) & 0xF; ysize = b & 0xF; break; case 2: PFR_CHECK( 2 ); xsize = PFR_NEXT_BYTE( p ); ysize = PFR_NEXT_BYTE( p ); break; case 3: PFR_CHECK( 4 ); xsize = PFR_NEXT_USHORT( p ); ysize = PFR_NEXT_USHORT( p ); break; default: ; } flags >>= 2; switch ( flags & 3 ) { case 0: advance = scaled_advance; break; case 1: PFR_CHECK( 1 ); advance = PFR_NEXT_INT8( p ) << 8; break; case 2: PFR_CHECK( 2 ); advance = PFR_NEXT_SHORT( p ); break; case 3: PFR_CHECK( 3 ); advance = PFR_NEXT_LONG( p ); break; default: ; } *axpos = xpos; *aypos = ypos; *axsize = xsize; *aysize = ysize; *aadvance = advance; *aformat = flags >> 2; *pdata = p; Exit: return error; Too_Short: error = PFR_Err_Invalid_Table; FT_ERROR(( "pfr_load_bitmap_metrics: invalid glyph data\n" )); goto Exit; } static FT_Error pfr_load_bitmap_bits( FT_Byte* p, FT_Byte* limit, FT_UInt format, FT_Bool decreasing, FT_Bitmap* target ) { FT_Error error = 0; PFR_BitWriterRec writer; if ( target->rows > 0 && target->width > 0 ) { pfr_bitwriter_init( &writer, target, decreasing ); switch ( format ) { case 0: /* packed bits */ pfr_bitwriter_decode_bytes( &writer, p, limit ); break; case 1: /* RLE1 */ pfr_bitwriter_decode_rle1( &writer, p, limit ); break; case 2: /* RLE2 */ pfr_bitwriter_decode_rle2( &writer, p, limit ); break; default: FT_ERROR(( "pfr_read_bitmap_data: invalid image type\n" )); error = PFR_Err_Invalid_File_Format; } } return error; } /*************************************************************************/ /*************************************************************************/ /***** *****/ /***** BITMAP LOADING *****/ /***** *****/ /*************************************************************************/ /*************************************************************************/ FT_LOCAL( FT_Error ) pfr_slot_load_bitmap( PFR_Slot glyph, PFR_Size size, FT_UInt glyph_index ) { FT_Error error; PFR_Face face = (PFR_Face) glyph->root.face; FT_Stream stream = face->root.stream; PFR_PhyFont phys = &face->phy_font; FT_ULong gps_offset; FT_ULong gps_size; PFR_Char character; PFR_Strike strike; character = &phys->chars[glyph_index]; /* Look-up a bitmap strike corresponding to the current */ /* character dimensions */ { FT_UInt n; strike = phys->strikes; for ( n = 0; n < phys->num_strikes; n++ ) { if ( strike->x_ppm == (FT_UInt)size->root.metrics.x_ppem && strike->y_ppm == (FT_UInt)size->root.metrics.y_ppem ) { goto Found_Strike; } strike++; } /* couldn't find it */ return PFR_Err_Invalid_Argument; } Found_Strike: /* Now lookup the glyph's position within the file */ { FT_UInt char_len; char_len = 4; if ( strike->flags & 1 ) char_len += 1; if ( strike->flags & 2 ) char_len += 1; if ( strike->flags & 4 ) char_len += 1; /* Access data directly in the frame to speed lookups */ if ( FT_STREAM_SEEK( phys->bct_offset + strike->bct_offset ) || FT_FRAME_ENTER( char_len * strike->num_bitmaps ) ) goto Exit; pfr_lookup_bitmap_data( stre... [truncated message content] |
|
From: Ehud S. <esh...@us...> - 2006-04-21 16:22:36
|
Update of /cvsroot/roadmap/roadmap_editor/src/freetype/include In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv22848/include Added Files: ft2build.h Log Message: Import freetype sources. --- NEW FILE: ft2build.h --- /***************************************************************************/ /* */ /* ft2build.h */ /* */ /* FreeType 2 build and setup macros. */ /* (Generic version) */ /* */ /* Copyright 1996-2001 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. */ /* */ /***************************************************************************/ /*************************************************************************/ /* */ /* This file corresponds to the default "ft2build.h" file for */ /* FreeType 2. It uses the "freetype" include root. */ /* */ /* Note that specific platforms might use a different configuration. */ /* See builds/unix/ft2unix.h for an example. */ /* */ /*************************************************************************/ #ifndef __FT2_BUILD_GENERIC_H__ #define __FT2_BUILD_GENERIC_H__ #include <freetype/config/ftheader.h> #endif /* __FT2_BUILD_GENERIC_H__ */ /* END */ |
|
From: Ehud S. <esh...@us...> - 2006-04-21 16:22:36
|
Update of /cvsroot/roadmap/roadmap_editor/src/freetype/src/cff In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv22848/src/cff Added Files: cff.c cffcmap.c cffdrivr.c cffgload.c cffload.c cffobjs.c cffparse.c Log Message: Import freetype sources. --- NEW FILE: cffload.c --- /***************************************************************************/ /* */ /* cffload.c */ /* */ /* OpenType and CFF data/program tables loader (body). */ /* */ /* Copyright 1996-2001, 2002, 2003, 2004, 2005 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> [...2273 lines suppressed...] { for ( idx = 0; idx < font->num_subfonts; idx++ ) cff_subfont_done( memory, font->subfonts[idx] ); FT_FREE( font->subfonts ); } cff_encoding_done( &font->encoding ); cff_charset_done( &font->charset, font->stream ); cff_subfont_done( memory, &font->top_font ); CFF_Done_FD_Select( &font->fd_select, font->stream ); FT_FREE( font->global_subrs ); FT_FREE( font->font_name ); } /* END */ --- NEW FILE: cffobjs.c --- /***************************************************************************/ /* */ /* cffobjs.c */ /* */ /* OpenType objects manager (body). */ /* */ /* Copyright 1996-2001, 2002, 2003, 2004, 2005 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_CALC_H #include FT_INTERNAL_STREAM_H #include FT_ERRORS_H #include FT_TRUETYPE_IDS_H #include FT_TRUETYPE_TAGS_H #include FT_INTERNAL_SFNT_H #include FT_SERVICE_POSTSCRIPT_CMAPS_H #include FT_INTERNAL_POSTSCRIPT_HINTS_H #include "cffobjs.h" #include "cffload.h" #include "cffcmap.h" #include "cfferrs.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_cffobjs /*************************************************************************/ /* */ /* SIZE FUNCTIONS */ /* */ /* Note that we store the global hints in the size's `internal' root */ /* field. */ /* */ /*************************************************************************/ #ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS static FT_Error sbit_size_reset( CFF_Size size ) { CFF_Face face; FT_Error error = CFF_Err_Ok; FT_ULong strike_index; FT_Size_Metrics* metrics; FT_Size_Metrics* sbit_metrics; SFNT_Service sfnt; metrics = &size->root.metrics; face = (CFF_Face)size->root.face; sfnt = (SFNT_Service)face->sfnt; sbit_metrics = &size->strike_metrics; error = sfnt->set_sbit_strike( face, metrics->x_ppem, metrics->y_ppem, &strike_index ); if ( !error ) { /* XXX: TODO: move this code to the SFNT module where it belongs */ #ifdef FT_OPTIMIZE_MEMORY FT_Byte* strike = face->sbit_table + 8 + strike_index*48; sbit_metrics->ascender = (FT_Char)strike[16] << 6; /* hori.ascender */ sbit_metrics->descender = (FT_Char)strike[17] << 6; /* hori.descender */ /* XXX: Is this correct? */ sbit_metrics->max_advance = ( (FT_Char)strike[22] + /* min_origin_SB */ strike[18] + /* max_width */ (FT_Char)strike[23] /* min_advance_SB */ ) << 6; #else /* !OPTIMIZE_MEMORY */ TT_SBit_Strike strike = face->sbit_strikes + strike_index; sbit_metrics->ascender = strike->hori.ascender << 6; sbit_metrics->descender = strike->hori.descender << 6; /* XXX: Is this correct? */ sbit_metrics->max_advance = ( strike->hori.min_origin_SB + strike->hori.max_width + strike->hori.min_advance_SB ) << 6; #endif /* !OPTIMIZE_MEMORY */ /* XXX: Is this correct? */ sbit_metrics->height = sbit_metrics->ascender - sbit_metrics->descender; sbit_metrics->x_ppem = metrics->x_ppem; sbit_metrics->y_ppem = metrics->y_ppem; size->strike_index = (FT_UInt)strike_index; } else { size->strike_index = 0xFFFFU; sbit_metrics->x_ppem = 0; sbit_metrics->y_ppem = 0; sbit_metrics->ascender = 0; sbit_metrics->descender = 0; sbit_metrics->height = 0; sbit_metrics->max_advance = 0; } return error; } #endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */ static PSH_Globals_Funcs cff_size_get_globals_funcs( CFF_Size size ) { CFF_Face face = (CFF_Face)size->root.face; CFF_Font font = (CFF_FontRec *)face->extra.data; PSHinter_Service pshinter = (PSHinter_Service)font->pshinter; FT_Module module; module = FT_Get_Module( size->root.face->driver->root.library, "pshinter" ); return ( module && pshinter && pshinter->get_globals_funcs ) ? pshinter->get_globals_funcs( module ) : 0; } FT_LOCAL_DEF( void ) cff_size_done( FT_Size cffsize ) /* CFF_Size */ { CFF_Size size = (CFF_Size)cffsize; if ( cffsize->internal ) { PSH_Globals_Funcs funcs; funcs = cff_size_get_globals_funcs( size ); if ( funcs ) funcs->destroy( (PSH_Globals)cffsize->internal ); cffsize->internal = 0; } } FT_LOCAL_DEF( FT_Error ) cff_size_init( FT_Size cffsize ) /* CFF_Size */ { CFF_Size size = (CFF_Size)cffsize; FT_Error error = CFF_Err_Ok; PSH_Globals_Funcs funcs = cff_size_get_globals_funcs( size ); if ( funcs ) { PSH_Globals globals; CFF_Face face = (CFF_Face)cffsize->face; CFF_Font font = (CFF_FontRec *)face->extra.data; CFF_SubFont subfont = &font->top_font; CFF_Private cpriv = &subfont->private_dict; PS_PrivateRec priv; /* IMPORTANT: The CFF and Type1 private dictionaries have */ /* slightly different structures; we need to */ /* synthetize a type1 dictionary on the fly here. */ { FT_UInt n, count; FT_MEM_ZERO( &priv, sizeof ( priv ) ); count = priv.num_blue_values = cpriv->num_blue_values; for ( n = 0; n < count; n++ ) priv.blue_values[n] = (FT_Short)cpriv->blue_values[n]; count = priv.num_other_blues = cpriv->num_other_blues; for ( n = 0; n < count; n++ ) priv.other_blues[n] = (FT_Short)cpriv->other_blues[n]; count = priv.num_family_blues = cpriv->num_family_blues; for ( n = 0; n < count; n++ ) priv.family_blues[n] = (FT_Short)cpriv->family_blues[n]; count = priv.num_family_other_blues = cpriv->num_family_other_blues; for ( n = 0; n < count; n++ ) priv.family_other_blues[n] = (FT_Short)cpriv->family_other_blues[n]; priv.blue_scale = cpriv->blue_scale; priv.blue_shift = (FT_Int)cpriv->blue_shift; priv.blue_fuzz = (FT_Int)cpriv->blue_fuzz; priv.standard_width[0] = (FT_UShort)cpriv->standard_width; priv.standard_height[0] = (FT_UShort)cpriv->standard_height; count = priv.num_snap_widths = cpriv->num_snap_widths; for ( n = 0; n < count; n++ ) priv.snap_widths[n] = (FT_Short)cpriv->snap_widths[n]; count = priv.num_snap_heights = cpriv->num_snap_heights; for ( n = 0; n < count; n++ ) priv.snap_heights[n] = (FT_Short)cpriv->snap_heights[n]; priv.force_bold = cpriv->force_bold; priv.language_group = cpriv->language_group; priv.lenIV = cpriv->lenIV; } error = funcs->create( cffsize->face->memory, &priv, &globals ); if ( !error ) cffsize->internal = (FT_Size_Internal)(void*)globals; } return error; } FT_LOCAL_DEF( FT_Error ) cff_size_reset( FT_Size cffsize, /* CFF_Size */ FT_UInt char_width, FT_UInt char_height ) { CFF_Size size = (CFF_Size)cffsize; PSH_Globals_Funcs funcs = cff_size_get_globals_funcs( size ); FT_Error error = CFF_Err_Ok; FT_Face face = cffsize->face; FT_UNUSED( char_width ); FT_UNUSED( char_height ); if ( funcs ) error = funcs->set_scale( (PSH_Globals)cffsize->internal, cffsize->metrics.x_scale, cffsize->metrics.y_scale, 0, 0 ); #ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS if ( face->face_flags & FT_FACE_FLAG_FIXED_SIZES ) { error = sbit_size_reset( size ); if ( !error && !( face->face_flags & FT_FACE_FLAG_SCALABLE ) ) cffsize->metrics = size->strike_metrics; } #endif if ( face->face_flags & FT_FACE_FLAG_SCALABLE ) return CFF_Err_Ok; else return error; } FT_LOCAL_DEF( FT_Error ) cff_point_size_reset( FT_Size cffsize, FT_F26Dot6 char_width, FT_F26Dot6 char_height, FT_UInt horz_resolution, FT_UInt vert_resolution ) { FT_UNUSED( char_width ); FT_UNUSED( char_height ); FT_UNUSED( horz_resolution ); FT_UNUSED( vert_resolution ); return cff_size_reset( cffsize, 0, 0 ); } /*************************************************************************/ /* */ /* SLOT FUNCTIONS */ /* */ /*************************************************************************/ FT_LOCAL_DEF( void ) cff_slot_done( FT_GlyphSlot slot ) { slot->internal->glyph_hints = 0; } FT_LOCAL_DEF( FT_Error ) cff_slot_init( FT_GlyphSlot slot ) { CFF_Face face = (CFF_Face)slot->face; CFF_Font font = (CFF_FontRec *)face->extra.data; PSHinter_Service pshinter = (PSHinter_Service)font->pshinter; if ( pshinter ) { FT_Module module; module = FT_Get_Module( slot->face->driver->root.library, "pshinter" ); if ( module ) { T2_Hints_Funcs funcs; funcs = pshinter->get_t2_funcs( module ); slot->internal->glyph_hints = (void*)funcs; } } return 0; } /*************************************************************************/ /* */ /* FACE FUNCTIONS */ /* */ /*************************************************************************/ static FT_String* cff_strcpy( FT_Memory memory, const FT_String* source ) { FT_Error error; FT_String* result = 0; FT_Int len = (FT_Int)ft_strlen( source ); if ( !FT_ALLOC( result, len + 1 ) ) { FT_MEM_COPY( result, source, len ); result[len] = 0; } FT_UNUSED( error ); return result; } FT_LOCAL_DEF( FT_Error ) cff_face_init( FT_Stream stream, FT_Face cffface, /* CFF_Face */ FT_Int face_index, FT_Int num_params, FT_Parameter* params ) { CFF_Face face = (CFF_Face)cffface; FT_Error error; SFNT_Service sfnt; FT_Service_PsCMaps psnames; PSHinter_Service pshinter; FT_Bool pure_cff = 1; FT_Bool sfnt_format = 0; #if 0 FT_FACE_FIND_GLOBAL_SERVICE( face, sfnt, SFNT ); FT_FACE_FIND_GLOBAL_SERVICE( face, psnames, POSTSCRIPT_NAMES ); FT_FACE_FIND_GLOBAL_SERVICE( face, pshinter, POSTSCRIPT_HINTER ); if ( !sfnt ) goto Bad_Format; #else sfnt = (SFNT_Service)FT_Get_Module_Interface( cffface->driver->root.library, "sfnt" ); if ( !sfnt ) goto Bad_Format; FT_FACE_FIND_GLOBAL_SERVICE( face, psnames, POSTSCRIPT_CMAPS ); pshinter = (PSHinter_Service)FT_Get_Module_Interface( cffface->driver->root.library, "pshinter" ); #endif /* create input stream from resource */ if ( FT_STREAM_SEEK( 0 ) ) goto Exit; /* check whether we have a valid OpenType file */ error = sfnt->init_face( stream, face, face_index, num_params, params ); if ( !error ) { if ( face->format_tag != 0x4F54544FL ) /* `OTTO'; OpenType/CFF font */ { FT_TRACE2(( "[not a valid OpenType/CFF font]\n" )); goto Bad_Format; } /* if we are performing a simple font format check, exit immediately */ if ( face_index < 0 ) return CFF_Err_Ok; /* UNDOCUMENTED! A CFF in an SFNT can have only a single font. */ if ( face_index > 0 ) { FT_ERROR(( "cff_face_init: invalid face index\n" )); error = CFF_Err_Invalid_Argument; goto Exit; } sfnt_format = 1; /* now, the font can be either an OpenType/CFF font, or an SVG CEF */ /* font; in the latter case it doesn't have a `head' table */ error = face->goto_table( face, TTAG_head, stream, 0 ); if ( !error ) { pure_cff = 0; /* load font directory */ error = sfnt->load_face( stream, face, face_index, num_params, params ); if ( error ) goto Exit; } else { /* load the `cmap' table explicitly */ error = sfnt->load_charmaps( face, stream ); if ( error ) goto Exit; /* XXX: we don't load the GPOS table, as OpenType Layout */ /* support will be added later to a layout library on top of */ /* FreeType 2 */ } /* now load the CFF part of the file */ error = face->goto_table( face, TTAG_CFF, stream, 0 ); if ( error ) goto Exit; } else { /* rewind to start of file; we are going to load a pure-CFF font */ if ( FT_STREAM_SEEK( 0 ) ) goto Exit; error = CFF_Err_Ok; } /* now load and parse the CFF table in the file */ { CFF_Font cff; CFF_FontRecDict dict; FT_Memory memory = cffface->memory; FT_Int32 flags; FT_UInt i; if ( FT_NEW( cff ) ) goto Exit; face->extra.data = cff; error = cff_font_load( stream, face_index, cff ); if ( error ) goto Exit; cff->pshinter = pshinter; cff->psnames = (void*)psnames; /* Complement the root flags with some interesting information. */ /* Note that this is only necessary for pure CFF and CEF fonts; */ /* SFNT based fonts use the `name' table instead. */ cffface->num_glyphs = cff->num_glyphs; dict = &cff->top_font.font_dict; /* we need the `PSNames' module for CFF and CEF formats */ /* which aren't CID-keyed */ if ( dict->cid_registry == 0xFFFFU && !psnames ) { FT_ERROR(( "cff_face_init:" )); FT_ERROR(( " cannot open CFF & CEF fonts\n" )); FT_ERROR(( " " )); FT_ERROR(( " without the `PSNames' module\n" )); goto Bad_Format; } if ( pure_cff ) { char* style_name = NULL; /* set up num_faces */ cffface->num_faces = cff->num_faces; /* compute number of glyphs */ if ( dict->cid_registry != 0xFFFFU ) cffface->num_glyphs = dict->cid_count; else cffface->num_glyphs = cff->charstrings_index.count; /* set global bbox, as well as EM size */ cffface->bbox.xMin = dict->font_bbox.xMin >> 16; cffface->bbox.yMin = dict->font_bbox.yMin >> 16; cffface->bbox.xMax = ( dict->font_bbox.xMax + 0xFFFFU ) >> 16; cffface->bbox.yMax = ( dict->font_bbox.yMax + 0xFFFFU ) >> 16; cffface->ascender = (FT_Short)( cffface->bbox.yMax ); cffface->descender = (FT_Short)( cffface->bbox.yMin ); cffface->height = (FT_Short)( ( ( cffface->ascender - cffface->descender ) * 12 ) / 10 ); if ( !dict->units_per_em ) dict->units_per_em = 1000; cffface->units_per_EM = dict->units_per_em; cffface->underline_position = (FT_Short)( dict->underline_position >> 16 ); cffface->underline_thickness = (FT_Short)( dict->underline_thickness >> 16 ); /* retrieve font family & style name */ cffface->family_name = cff_index_get_name( &cff->name_index, face_index ); if ( cffface->family_name ) { char* full = cff_index_get_sid_string( &cff->string_index, dict->full_name, psnames ); char* fullp = full; char* family = cffface->family_name; char* family_name = 0; if ( dict->family_name ) { family_name = cff_index_get_sid_string( &cff->string_index, dict->family_name, psnames); if ( family_name ) family = family_name; } /* We try to extract the style name from the full name. */ /* We need to ignore spaces and dashes during the search. */ if ( full && family ) { while ( *fullp ) { /* skip common characters at the start of both strings */ if ( *fullp == *family ) { family++; fullp++; continue; } /* ignore spaces and dashes in full name during comparison */ if ( *fullp == ' ' || *fullp == '-' ) { fullp++; continue; } /* ignore spaces and dashes in family name during comparison */ if ( *family == ' ' || *family == '-' ) { family++; continue; } if ( !*family && *fullp ) { /* The full name begins with the same characters as the */ /* family name, with spaces and dashes removed. In this */ /* case, the remaining string in `fullp' will be used as */ /* the style name. */ style_name = cff_strcpy( memory, fullp ); } break; } if ( family_name ) FT_FREE( family_name ); FT_FREE( full ); } } else { char *cid_font_name = cff_index_get_sid_string( &cff->string_index, dict->cid_font_name, psnames ); /* do we have a `/FontName' for a CID-keyed font? */ if ( cid_font_name ) cffface->family_name = cid_font_name; } if ( style_name ) cffface->style_name = style_name; else /* assume "Regular" style if we don't know better */ cffface->style_name = cff_strcpy( memory, (char *)"Regular" ); /*******************************************************************/ /* */ /* Compute face flags. */ /* */ flags = FT_FACE_FLAG_SCALABLE | /* scalable outlines */ FT_FACE_FLAG_HORIZONTAL; /* horizontal data */ if ( sfnt_format ) flags |= FT_FACE_FLAG_SFNT; /* fixed width font? */ if ( dict->is_fixed_pitch ) flags |= FT_FACE_FLAG_FIXED_WIDTH; /* XXX: WE DO NOT SUPPORT KERNING METRICS IN THE GPOS TABLE FOR NOW */ #if 0 /* kerning available? */ if ( face->kern_pairs ) flags |= FT_FACE_FLAG_KERNING; #endif cffface->face_flags = flags; /*******************************************************************/ /* */ /* Compute style flags. */ /* */ flags = 0; if ( dict->italic_angle ) flags |= FT_STYLE_FLAG_ITALIC; { char *weight = cff_index_get_sid_string( &cff->string_index, dict->weight, psnames ); if ( weight ) if ( !ft_strcmp( weight, "Bold" ) || !ft_strcmp( weight, "Black" ) ) flags |= FT_STYLE_FLAG_BOLD; FT_FREE( weight ); } /* double check */ if ( !(flags & FT_STYLE_FLAG_BOLD) && cffface->style_name ) if ( !strncmp( cffface->style_name, "Bold", 4 ) || !strncmp( cffface->style_name, "Black", 5 ) ) flags |= FT_STYLE_FLAG_BOLD; cffface->style_flags = flags; } else { if ( !dict->units_per_em ) dict->units_per_em = face->root.units_per_EM; } /* handle font matrix settings in subfonts (if any) */ for ( i = cff->num_subfonts; i > 0; i-- ) { CFF_FontRecDict sub = &cff->subfonts[i - 1]->font_dict; CFF_FontRecDict top = &cff->top_font.font_dict; if ( sub->units_per_em ) { FT_Matrix scale; scale.xx = scale.yy = (FT_Fixed)FT_DivFix( top->units_per_em, sub->units_per_em ); scale.xy = scale.yx = 0; FT_Matrix_Multiply( &scale, &sub->font_matrix ); FT_Vector_Transform( &sub->font_offset, &scale ); } else { sub->font_matrix = top->font_matrix; sub->font_offset = top->font_offset; } } #ifndef FT_CONFIG_OPTION_NO_GLYPH_NAMES /* CID-keyed CFF fonts don't have glyph names -- the SFNT loader */ /* has unset this flag because of the 3.0 `post' table */ if ( dict->cid_registry == 0xFFFFU ) cffface->face_flags |= FT_FACE_FLAG_GLYPH_NAMES; #endif /*******************************************************************/ /* */ /* Compute char maps. */ /* */ /* Try to synthetize a Unicode charmap if there is none available */ /* already. If an OpenType font contains a Unicode "cmap", we */ /* will use it, whatever be in the CFF part of the file. */ { FT_CharMapRec cmaprec; FT_CharMap cmap; FT_UInt nn; CFF_Encoding encoding = &cff->encoding; for ( nn = 0; nn < (FT_UInt)cffface->num_charmaps; nn++ ) { cmap = cffface->charmaps[nn]; /* Windows Unicode (3,1)? */ if ( cmap->platform_id == 3 && cmap->encoding_id == 1 ) goto Skip_Unicode; /* Deprecated Unicode platform id? */ if ( cmap->platform_id == 0 ) goto Skip_Unicode; /* Standard Unicode (deprecated) */ } /* since CID-keyed fonts don't contain glyph names, we can't */ /* construct a cmap */ if ( pure_cff && cff->top_font.font_dict.cid_registry != 0xFFFFU ) goto Exit; /* we didn't find a Unicode charmap -- synthetize one */ cmaprec.face = cffface; cmaprec.platform_id = 3; cmaprec.encoding_id = 1; cmaprec.encoding = FT_ENCODING_UNICODE; nn = (FT_UInt)cffface->num_charmaps; FT_CMap_New( &cff_cmap_unicode_class_rec, NULL, &cmaprec, NULL ); /* if no Unicode charmap was previously selected, select this one */ if ( cffface->charmap == NULL && nn != (FT_UInt)cffface->num_charmaps ) cffface->charmap = cffface->charmaps[nn]; Skip_Unicode: if ( encoding->count > 0 ) { FT_CMap_Class clazz; cmaprec.face = cffface; cmaprec.platform_id = 7; /* Adobe platform id */ if ( encoding->offset == 0 ) { cmaprec.encoding_id = TT_ADOBE_ID_STANDARD; cmaprec.encoding = FT_ENCODING_ADOBE_STANDARD; clazz = &cff_cmap_encoding_class_rec; } else if ( encoding->offset == 1 ) { cmaprec.encoding_id = TT_ADOBE_ID_EXPERT; cmaprec.encoding = FT_ENCODING_ADOBE_EXPERT; clazz = &cff_cmap_encoding_class_rec; } else { cmaprec.encoding_id = TT_ADOBE_ID_CUSTOM; cmaprec.encoding = FT_ENCODING_ADOBE_CUSTOM; clazz = &cff_cmap_encoding_class_rec; } FT_CMap_New( clazz, NULL, &cmaprec, NULL ); } } } Exit: return error; Bad_Format: error = CFF_Err_Unknown_File_Format; goto Exit; } FT_LOCAL_DEF( void ) cff_face_done( FT_Face cffface ) /* CFF_Face */ { CFF_Face face = (CFF_Face)cffface; FT_Memory memory = cffface->memory; SFNT_Service sfnt = (SFNT_Service)face->sfnt; if ( sfnt ) sfnt->done_face( face ); { CFF_Font cff = (CFF_Font)face->extra.data; if ( cff ) { cff_font_done( cff ); FT_FREE( face->extra.data ); } } } FT_LOCAL_DEF( FT_Error ) cff_driver_init( FT_Module module ) { FT_UNUSED( module ); return CFF_Err_Ok; } FT_LOCAL_DEF( void ) cff_driver_done( FT_Module module ) { FT_UNUSED( module ); } /* END */ --- NEW FILE: cff.c --- /***************************************************************************/ /* */ /* cff.c */ /* */ /* FreeType OpenType driver component (body only). */ /* */ /* Copyright 1996-2001, 2002 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. */ /* */ /***************************************************************************/ #define FT_MAKE_OPTION_SINGLE_OBJECT #include <ft2build.h> #include "cffdrivr.c" #include "cffparse.c" #include "cffload.c" #include "cffobjs.c" #include "cffgload.c" #include "cffcmap.c" /* END */ --- NEW FILE: cffdrivr.c --- /***************************************************************************/ /* */ /* cffdrivr.c */ /* */ /* OpenType font driver implementation (body). */ /* */ /* Copyright 1996-2001, 2002, 2003, 2004, 2005 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_FREETYPE_H #include FT_INTERNAL_DEBUG_H #include FT_INTERNAL_STREAM_H #include FT_INTERNAL_SFNT_H #include FT_TRUETYPE_IDS_H #include FT_SERVICE_POSTSCRIPT_CMAPS_H #include FT_SERVICE_POSTSCRIPT_INFO_H #include FT_SERVICE_TT_CMAP_H #include "cffdrivr.h" #include "cffgload.h" #include "cffload.h" #include "cffcmap.h" #include "cfferrs.h" #include FT_SERVICE_XFREE86_NAME_H #include FT_SERVICE_GLYPH_DICT_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_cffdriver /*************************************************************************/ /*************************************************************************/ /*************************************************************************/ /**** ****/ /**** ****/ /**** F A C E S ****/ /**** ****/ /**** ****/ /*************************************************************************/ /*************************************************************************/ /*************************************************************************/ #undef PAIR_TAG #define PAIR_TAG( left, right ) ( ( (FT_ULong)left << 16 ) | \ (FT_ULong)right ) /*************************************************************************/ /* */ /* <Function> */ /* cff_get_kerning */ /* */ /* <Description> */ /* A driver method used to return the kerning vector between two */ /* glyphs of the same face. */ /* */ /* <Input> */ /* face :: A handle to the source face object. */ /* */ /* left_glyph :: The index of the left glyph in the kern pair. */ /* */ /* right_glyph :: The index of the right glyph in the kern pair. */ /* */ /* <Output> */ /* kerning :: The kerning vector. This is in font units for */ /* scalable formats, and in pixels for fixed-sizes */ /* formats. */ /* */ /* <Return> */ /* FreeType error code. 0 means success. */ /* */ /* <Note> */ /* Only horizontal layouts (left-to-right & right-to-left) are */ /* supported by this function. Other layouts, or more sophisticated */ /* kernings, are out of scope of this method (the basic driver */ /* interface is meant to be simple). */ /* */ /* They can be implemented by format-specific interfaces. */ /* */ FT_CALLBACK_DEF( FT_Error ) cff_get_kerning( FT_Face ttface, /* TT_Face */ FT_UInt left_glyph, FT_UInt right_glyph, FT_Vector* kerning ) { TT_Face face = (TT_Face)ttface; SFNT_Service sfnt = (SFNT_Service)face->sfnt; kerning->x = 0; kerning->y = 0; if ( sfnt ) kerning->x = sfnt->get_kerning( face, left_glyph, right_glyph ); return CFF_Err_Ok; } #undef PAIR_TAG /*************************************************************************/ /* */ /* <Function> */ /* Load_Glyph */ /* */ /* <Description> */ /* A driver method used to load a glyph within a given glyph slot. */ /* */ /* <Input> */ /* slot :: A handle to the target slot object where the glyph */ /* will be loaded. */ /* */ /* size :: A handle to the source face size at which the glyph */ /* must be scaled, loaded, etc. */ /* */ /* glyph_index :: The index of the glyph in the font file. */ /* */ /* load_flags :: A flag indicating what to load for this glyph. The */ /* FT_LOAD_??? constants can be used to control the */ /* glyph loading process (e.g., whether the outline */ /* should be scaled, whether to load bitmaps or not, */ /* whether to hint the outline, etc). */ /* */ /* <Return> */ /* FreeType error code. 0 means success. */ /* */ FT_CALLBACK_DEF( FT_Error ) Load_Glyph( FT_GlyphSlot cffslot, /* CFF_GlyphSlot */ FT_Size cffsize, /* CFF_Size */ FT_UInt glyph_index, FT_Int32 load_flags ) { FT_Error error; CFF_GlyphSlot slot = (CFF_GlyphSlot)cffslot; CFF_Size size = (CFF_Size)cffsize; if ( !slot ) return CFF_Err_Invalid_Slot_Handle; /* check whether we want a scaled outline or bitmap */ if ( !size ) load_flags |= FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING; if ( load_flags & FT_LOAD_NO_SCALE ) size = NULL; /* reset the size object if necessary */ if ( size ) { /* these two objects must have the same parent */ if ( cffsize->face != cffslot->face ) return CFF_Err_Invalid_Face_Handle; } /* now load the glyph outline if necessary */ error = cff_slot_load( slot, size, glyph_index, load_flags ); /* force drop-out mode to 2 - irrelevant now */ /* slot->outline.dropout_mode = 2; */ return error; } /* * GLYPH DICT SERVICE * */ static FT_Error cff_get_glyph_name( CFF_Face face, FT_UInt glyph_index, FT_Pointer buffer, FT_UInt buffer_max ) { CFF_Font font = (CFF_Font)face->extra.data; FT_Memory memory = FT_FACE_MEMORY( face ); FT_String* gname; FT_UShort sid; FT_Service_PsCMaps psnames; FT_Error error; FT_FACE_FIND_GLOBAL_SERVICE( face, psnames, POSTSCRIPT_CMAPS ); if ( !psnames ) { FT_ERROR(( "cff_get_glyph_name:" )); FT_ERROR(( " cannot get glyph name from CFF & CEF fonts\n" )); FT_ERROR(( " " )); FT_ERROR(( " without the `PSNames' module\n" )); error = CFF_Err_Unknown_File_Format; goto Exit; } /* first, locate the sid in the charset table */ sid = font->charset.sids[glyph_index]; /* now, lookup the name itself */ gname = cff_index_get_sid_string( &font->string_index, sid, psnames ); if ( gname && buffer_max > 0 ) { FT_UInt len = (FT_UInt)ft_strlen( gname ); if ( len >= buffer_max ) len = buffer_max - 1; FT_MEM_COPY( buffer, gname, len ); ((FT_Byte*)buffer)[len] = 0; } FT_FREE( gname ); error = CFF_Err_Ok; Exit: return error; } static FT_UInt cff_get_name_index( CFF_Face face, FT_String* glyph_name ) { CFF_Font cff; CFF_Charset charset; FT_Service_PsCMaps psnames; FT_Memory memory = FT_FACE_MEMORY( face ); FT_String* name; FT_UShort sid; FT_UInt i; FT_Int result; cff = (CFF_FontRec *)face->extra.data; charset = &cff->charset; FT_FACE_FIND_GLOBAL_SERVICE( face, psnames, POSTSCRIPT_CMAPS ); if ( !psnames ) return 0; for ( i = 0; i < cff->num_glyphs; i++ ) { sid = charset->sids[i]; if ( sid > 390 ) name = cff_index_get_name( &cff->string_index, sid - 391 ); else name = (FT_String *)psnames->adobe_std_strings( sid ); result = ft_strcmp( glyph_name, name ); if ( sid > 390 ) FT_FREE( name ); if ( !result ) return i; } return 0; } static const FT_Service_GlyphDictRec cff_service_glyph_dict = { (FT_GlyphDict_GetNameFunc) cff_get_glyph_name, (FT_GlyphDict_NameIndexFunc)cff_get_name_index, }; /* * POSTSCRIPT INFO SERVICE * */ static FT_Int cff_ps_has_glyph_names( FT_Face face ) { return ( face->face_flags & FT_FACE_FLAG_GLYPH_NAMES ) > 0; } static const FT_Service_PsInfoRec cff_service_ps_info = { (PS_GetFontInfoFunc) NULL, /* unsupported with CFF fonts */ (PS_HasGlyphNamesFunc) cff_ps_has_glyph_names, (PS_GetFontPrivateFunc)NULL /* unsupported with CFF fonts */ }; /* * TT CMAP INFO * * If the charmap is a synthetic Unicode encoding cmap or * a Type 1 standard (or expert) encoding cmap, hide TT CMAP INFO * service defined in SFNT module. * * Otherwise call the service function in the sfnt module. * */ static FT_Error cff_get_cmap_info( FT_CharMap charmap, TT_CMapInfo *cmap_info ) { FT_CMap cmap = FT_CMAP( charmap ); FT_Error error = CFF_Err_Ok; cmap_info->language = 0; if ( cmap->clazz != &cff_cmap_encoding_class_rec && cmap->clazz != &cff_cmap_unicode_class_rec ) { FT_Face face = FT_CMAP_FACE( cmap ); FT_Library library = FT_FACE_LIBRARY( face ); FT_Module sfnt = FT_Get_Module( library, "sfnt" ); FT_Service_TTCMaps service = (FT_Service_TTCMaps)ft_module_get_service( sfnt, FT_SERVICE_ID_TT_CMAP ); if ( service && service->get_cmap_info ) error = service->get_cmap_info( charmap, cmap_info ); } return error; } static const FT_Service_TTCMapsRec cff_service_get_cmap_info = { (TT_CMap_Info_GetFunc)cff_get_cmap_info }; /*************************************************************************/ /*************************************************************************/ /*************************************************************************/ /**** ****/ /**** ****/ /**** D R I V E R I N T E R F A C E ****/ /**** ****/ /**** ****/ /*************************************************************************/ /*************************************************************************/ /*************************************************************************/ static const FT_ServiceDescRec cff_services[] = { { FT_SERVICE_ID_XF86_NAME, FT_XF86_FORMAT_CFF }, { FT_SERVICE_ID_POSTSCRIPT_INFO, &cff_service_ps_info }, #ifndef FT_CONFIG_OPTION_NO_GLYPH_NAMES { FT_SERVICE_ID_GLYPH_DICT, &cff_service_glyph_dict }, #endif { FT_SERVICE_ID_TT_CMAP, &cff_service_get_cmap_info }, { NULL, NULL } }; FT_CALLBACK_DEF( FT_Module_Interface ) cff_get_interface( FT_Module driver, /* CFF_Driver */ const char* module_interface ) { FT_Module sfnt; FT_Module_Interface result; result = ft_service_list_lookup( cff_services, module_interface ); if ( result != NULL ) return result; /* we pass our request to the `sfnt' module */ sfnt = FT_Get_Module( driver->library, "sfnt" ); return sfnt ? sfnt->clazz->get_interface( sfnt, module_interface ) : 0; } /* The FT_DriverInterface structure is defined in ftdriver.h. */ FT_CALLBACK_TABLE_DEF const FT_Driver_ClassRec cff_driver_class = { /* begin with the FT_Module_Class fields */ { FT_MODULE_FONT_DRIVER | FT_MODULE_DRIVER_SCALABLE | FT_MODULE_DRIVER_HAS_HINTER, sizeof( CFF_DriverRec ), "cff", 0x10000L, 0x20000L, 0, /* module-specific interface */ cff_driver_init, cff_driver_done, cff_get_interface, }, /* now the specific driver fields */ sizeof( TT_FaceRec ), sizeof( CFF_SizeRec ), sizeof( CFF_GlyphSlotRec ), cff_face_init, cff_face_done, cff_size_init, cff_size_done, cff_slot_init, cff_slot_done, cff_point_size_reset, cff_size_reset, Load_Glyph, cff_get_kerning, 0, /* FT_Face_AttachFunc */ 0 /* FT_Face_GetAdvancesFunc */ }; /* END */ --- NEW FILE: cffcmap.c --- /***************************************************************************/ /* */ /* cffcmap.c */ /* */ /* CFF character mapping table (cmap) support (body). */ /* */ /* Copyright 2002, 2003, 2004, 2005 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 "cffcmap.h" #include "cffload.h" #include "cfferrs.h" /*************************************************************************/ /*************************************************************************/ /***** *****/ /***** CFF STANDARD (AND EXPERT) ENCODING CMAPS *****/ /***** *****/ /*************************************************************************/ /*************************************************************************/ FT_CALLBACK_DEF( FT_Error ) cff_cmap_encoding_init( CFF_CMapStd cmap ) { TT_Face face = (TT_Face)FT_CMAP_FACE( cmap ); CFF_Font cff = (CFF_Font)face->extra.data; CFF_Encoding encoding = &cff->encoding; cmap->gids = encoding->codes; return 0; } FT_CALLBACK_DEF( void ) cff_cmap_encoding_done( CFF_CMapStd cmap ) { cmap->gids = NULL; } FT_CALLBACK_DEF( FT_UInt ) cff_cmap_encoding_char_index( CFF_CMapStd cmap, FT_UInt32 char_code ) { FT_UInt result = 0; if ( char_code < 256 ) result = cmap->gids[char_code]; return result; } FT_CALLBACK_DEF( FT_UInt ) cff_cmap_encoding_char_next( CFF_CMapStd cmap, FT_UInt32 *pchar_code ) { FT_UInt result = 0; FT_UInt32 char_code = *pchar_code; *pchar_code = 0; if ( char_code < 255 ) { FT_UInt code = (FT_UInt)(char_code + 1); for (;;) { if ( code >= 256 ) break; result = cmap->gids[code]; if ( result != 0 ) { *pchar_code = code; break; } code++; } } return result; } FT_CALLBACK_TABLE_DEF const FT_CMap_ClassRec cff_cmap_encoding_class_rec = { sizeof ( CFF_CMapStdRec ), (FT_CMap_InitFunc) cff_cmap_encoding_init, (FT_CMap_DoneFunc) cff_cmap_encoding_done, (FT_CMap_CharIndexFunc)cff_cmap_encoding_char_index, (FT_CMap_CharNextFunc) cff_cmap_encoding_char_next }; /*************************************************************************/ /*************************************************************************/ /***** *****/ /***** CFF SYNTHETIC UNICODE ENCODING CMAP *****/ /***** *****/ /*************************************************************************/ /*************************************************************************/ FT_CALLBACK_DEF( FT_Int ) cff_cmap_uni_pair_compare( const void* pair1, const void* pair2 ) { FT_UInt32 u1 = ((CFF_CMapUniPair)pair1)->unicode; FT_UInt32 u2 = ((CFF_CMapUniPair)pair2)->unicode; if ( u1 < u2 ) return -1; if ( u1 > u2 ) return +1; return 0; } FT_CALLBACK_DEF( FT_Error ) cff_cmap_unicode_init( CFF_CMapUnicode cmap ) { FT_Error error; FT_UInt count; TT_Face face = (TT_Face)FT_CMAP_FACE( cmap ); FT_Memory memory = FT_FACE_MEMORY( face ); CFF_Font cff = (CFF_Font)face->extra.data; CFF_Charset charset = &cff->charset; FT_Service_PsCMaps psnames = (FT_Service_PsCMaps)cff->psnames; /* can't build Unicode map for CID-keyed font */ if ( !charset->sids ) { error = CFF_Err_Invalid_Argument; goto Exit; } cmap->num_pairs = 0; cmap->pairs = NULL; count = cff->num_glyphs; if ( !FT_NEW_ARRAY( cmap->pairs, count ) ) { FT_UInt n, new_count; CFF_CMapUniPair pair; FT_UInt32 uni_code; pair = cmap->pairs; for ( n = 0; n < count; n++ ) { FT_UInt sid = charset->sids[n]; const char* gname; gname = cff_index_get_sid_string( &cff->string_index, sid, psnames ); /* build unsorted pair table by matching glyph names */ if ( gname ) { uni_code = psnames->unicode_value( gname ); if ( uni_code != 0 ) { pair->unicode = uni_code; pair->gindex = n; pair++; } FT_FREE( gname ); } } new_count = (FT_UInt)( pair - cmap->pairs ); if ( new_count == 0 ) { /* there are no unicode characters in here! */ FT_FREE( cmap->pairs ); error = CFF_Err_Invalid_Argument; } else { /* re-allocate if the new array is much smaller than the original */ /* one */ if ( new_count != count && new_count < count / 2 ) { (void)FT_RENEW_ARRAY( cmap->pairs, count, new_count ); error = CFF_Err_Ok; } /* sort the pairs table to allow efficient binary searches */ ft_qsort( cmap->pairs, new_count, sizeof ( CFF_CMapUniPairRec ), cff_cmap_uni_pair_compare ); cmap->num_pairs = new_count; } } Exit: return error; } FT_CALLBACK_DEF( void ) cff_cmap_unicode_done( CFF_CMapUnicode cmap ) { FT_Face face = FT_CMAP_FACE( cmap ); FT_Memory memory = FT_FACE_MEMORY( face ); FT_FREE( cmap->pairs ); cmap->num_pairs = 0; } FT_CALLBACK_DEF( FT_UInt ) cff_cmap_unicode_char_index( CFF_CMapUnicode cmap, FT_UInt32 char_code ) { FT_UInt min = 0; FT_UInt max = cmap->num_pairs; FT_UInt mid; CFF_CMapUniPair pair; while ( min < max ) { mid = min + ( max - min ) / 2; pair = cmap->pairs + mid; if ( pair->unicode == char_code ) return pair->gindex; if ( pair->unicode < char_code ) min = mid + 1; else max = mid; } return 0; } FT_CALLBACK_DEF( FT_UInt ) cff_cmap_unicode_char_next( CFF_CMapUnicode cmap, FT_UInt32 *pchar_code ) { FT_UInt result = 0; FT_UInt32 char_code = *pchar_code + 1; Restart: { FT_UInt min = 0; FT_UInt max = cmap->num_pairs; FT_UInt mid; CFF_CMapUniPair pair; while ( min < max ) { mid = min + ( ( max - min ) >> 1 ); pair = cmap->pairs + mid; if ( pair->unicode == char_code ) { result = pair->gindex; if ( result != 0 ) goto Exit; char_code++; goto Restart; } if ( pair->unicode < char_code ) min = mid+1; else max = mid; } /* we didn't find it, but we have a pair just above it */ char_code = 0; if ( min < cmap->num_pairs ) { pair = cmap->pairs + min; result = pair->gindex; if ( result != 0 ) char_code = pair->unicode; } } Exit: *pchar_code = char_code; return result; } FT_CALLBACK_TABLE_DEF const FT_CMap_ClassRec cff_cmap_unicode_class_rec = { sizeof ( CFF_CMapUnicodeRec ), (FT_CMap_InitFunc) cff_cmap_unicode_init, (FT_CMap_DoneFunc) cff_cmap_unicode_done, (FT_CMap_CharIndexFunc)cff_cmap_unicode_char_index, (FT_CMap_CharNextFunc) cff_cmap_unicode_char_next }; /* END */ --- NEW FILE: cffgload.c --- /***************************************************************************/ /* */ /* cffgload.c */ /* */ /* OpenType Glyph Loader (body). */ /* */ /* Copyright 1996-2001, 2002, 2003, 2004, 2005 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> [...2566 lines suppressed...] { cbox.xMin &= -64; cbox.yMin &= -64; cbox.xMax = ( cbox.xMax + 63 ) & -64; cbox.yMax = ( cbox.yMax + 63 ) & -64; } metrics->width = cbox.xMax - cbox.xMin; metrics->height = cbox.yMax - cbox.yMin; metrics->horiBearingX = cbox.xMin; metrics->horiBearingY = cbox.yMax; } } return error; } /* END */ --- NEW FILE: cffparse.c --- /***************************************************************************/ /* */ /* cffparse.c */ /* */ /* CFF token stream parser (body) */ /* */ /* Copyright 1996-2001, 2002, 2003, 2004 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 "cffparse.h" #include FT_INTERNAL_STREAM_H #include "cfferrs.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_cffparse enum { cff_kind_none = 0, cff_kind_num, cff_kind_fixed, cff_kind_fixed_thousand, cff_kind_string, cff_kind_bool, cff_kind_delta, cff_kind_callback, cff_kind_max /* do not remove */ }; /* now generate handlers for the most simple fields */ typedef FT_Error (*CFF_Field_Reader)( CFF_Parser parser ); typedef struct CFF_Field_Handler_ { int kind; int code; FT_UInt offset; FT_Byte size; CFF_Field_Reader reader; FT_UInt array_max; FT_UInt count_offset; } CFF_Field_Handler; FT_LOCAL_DEF( void ) cff_parser_init( CFF_Parser parser, FT_UInt code, void* object ) { FT_MEM_ZERO( parser, sizeof ( *parser ) ); parser->top = parser->stac... [truncated message content] |
|
From: Ehud S. <esh...@us...> - 2006-04-21 16:22:35
|
Update of /cvsroot/roadmap/roadmap_editor/src/freetype/include/freetype/cache In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv22848/include/freetype/cache Added Files: ftccache.h ftccmap.h ftcglyph.h ftcimage.h ftcmanag.h ftcmru.h ftcsbits.h Log Message: Import freetype sources. --- NEW FILE: ftcimage.h --- /***************************************************************************/ /* */ /* ftcimage.h */ /* */ /* FreeType Generic Image cache (specification) */ /* */ /* Copyright 2000-2001, 2002, 2003 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. */ /* */ /***************************************************************************/ /* * FTC_ICache is an _abstract_ cache used to store a single FT_Glyph * image per cache node. * * FTC_ICache extends FTC_GCache. For an implementation example, * see FTC_ImageCache in `src/cache/ftbasic.c'. */ /*************************************************************************/ /* */ /* Each image cache really manages FT_Glyph objects. */ /* */ /*************************************************************************/ #ifndef __FTCIMAGE_H__ #define __FTCIMAGE_H__ #include <ft2build.h> #include FT_CACHE_H #include FT_CACHE_INTERNAL_GLYPH_H FT_BEGIN_HEADER /* the FT_Glyph image node type - we store only 1 glyph per node */ typedef struct FTC_INodeRec_ { FTC_GNodeRec gnode; FT_Glyph glyph; } FTC_INodeRec, *FTC_INode; #define FTC_INODE( x ) ( (FTC_INode)( x ) ) #define FTC_INODE_GINDEX( x ) FTC_GNODE(x)->gindex #define FTC_INODE_FAMILY( x ) FTC_GNODE(x)->family typedef FT_Error (*FTC_IFamily_LoadGlyphFunc)( FTC_Family family, FT_UInt gindex, FTC_Cache cache, FT_Glyph *aglyph ); typedef struct FTC_IFamilyClassRec_ { FTC_MruListClassRec clazz; FTC_IFamily_LoadGlyphFunc family_load_glyph; } FTC_IFamilyClassRec; typedef const FTC_IFamilyClassRec* FTC_IFamilyClass; #define FTC_IFAMILY_CLASS( x ) ((FTC_IFamilyClass)(x)) #define FTC_CACHE__IFAMILY_CLASS( x ) \ FTC_IFAMILY_CLASS( FTC_CACHE__GCACHE_CLASS(x)->family_class ) /* can be used as a @FTC_Node_FreeFunc */ FT_EXPORT( void ) FTC_INode_Free( FTC_INode inode, FTC_Cache cache ); /* Can be used as @FTC_Node_NewFunc. `gquery.index' and `gquery.family' * must be set correctly. This function will call the `family_load_glyph' * method to load the FT_Glyph into the cache node. */ FT_EXPORT( FT_Error ) FTC_INode_New( FTC_INode *pinode, FTC_GQuery gquery, FTC_Cache cache ); /* can be used as @FTC_Node_WeightFunc */ FT_EXPORT( FT_ULong ) FTC_INode_Weight( FTC_INode inode ); /* */ FT_END_HEADER #endif /* __FTCIMAGE_H__ */ /* END */ --- NEW FILE: ftcmanag.h --- /***************************************************************************/ /* */ /* ftcmanag.h */ /* */ /* FreeType Cache Manager (specification). */ /* */ /* Copyright 2000-2001, 2003, 2004 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. */ /* */ /***************************************************************************/ /*************************************************************************/ /* */ /* A cache manager is in charge of the following: */ /* */ /* - Maintain a mapping between generic FTC_FaceIDs and live FT_Face */ /* objects. The mapping itself is performed through a user-provided */ /* callback. However, the manager maintains a small cache of FT_Face */ /* and FT_Size objects in order to speed up things considerably. */ /* */ /* - Manage one or more cache objects. Each cache is in charge of */ /* holding a varying number of `cache nodes'. Each cache node */ /* represents a minimal amount of individually accessible cached */ /* data. For example, a cache node can be an FT_Glyph image */ /* containing a vector outline, or some glyph metrics, or anything */ /* else. */ /* */ /* Each cache node has a certain size in bytes that is added to the */ /* total amount of `cache memory' within the manager. */ /* */ /* All cache nodes are located in a global LRU list, where the oldest */ /* node is at the tail of the list. */ /* */ /* Each node belongs to a single cache, and includes a reference */ /* count to avoid destroying it (due to caching). */ /* */ /*************************************************************************/ /*************************************************************************/ /*************************************************************************/ /*************************************************************************/ /*************************************************************************/ /*************************************************************************/ /********* *********/ /********* WARNING, THIS IS BETA CODE. *********/ /********* *********/ /*************************************************************************/ /*************************************************************************/ /*************************************************************************/ /*************************************************************************/ /*************************************************************************/ #ifndef __FTCMANAG_H__ #define __FTCMANAG_H__ #include <ft2build.h> #include FT_CACHE_H #include FT_CACHE_INTERNAL_MRU_H #include FT_CACHE_INTERNAL_CACHE_H FT_BEGIN_HEADER /*************************************************************************/ /* */ /* <Section> */ /* cache_subsystem */ /* */ /*************************************************************************/ #define FTC_MAX_FACES_DEFAULT 2 #define FTC_MAX_SIZES_DEFAULT 4 #define FTC_MAX_BYTES_DEFAULT 200000L /* ~200kByte by default */ /* maximum number of caches registered in a single manager */ #define FTC_MAX_CACHES 16 typedef struct FTC_ManagerRec_ { FT_Library library; FT_Memory memory; FTC_Node nodes_list; FT_ULong max_weight; FT_ULong cur_weight; FT_UInt num_nodes; FTC_Cache caches[FTC_MAX_CACHES]; FT_UInt num_caches; FTC_MruListRec faces; FTC_MruListRec sizes; FT_Pointer request_data; FTC_Face_Requester request_face; } FTC_ManagerRec; /*************************************************************************/ /* */ /* <Function> */ /* FTC_Manager_Compress */ /* */ /* <Description> */ /* This function is used to check the state of the cache manager if */ /* its `num_bytes' field is greater than its `max_bytes' field. It */ /* will flush as many old cache nodes as possible (ignoring cache */ /* nodes with a non-zero reference count). */ /* */ /* <InOut> */ /* manager :: A handle to the cache manager. */ /* */ /* <Note> */ /* Client applications should not call this function directly. It is */ /* normally invoked by specific cache implementations. */ /* */ /* The reason this function is exported is to allow client-specific */ /* cache classes. */ /* */ FT_EXPORT( void ) FTC_Manager_Compress( FTC_Manager manager ); /* try to flush `count' old nodes from the cache; return the number * of really flushed nodes */ FT_EXPORT( FT_UInt ) FTC_Manager_FlushN( FTC_Manager manager, FT_UInt count ); /* this must be used internally for the moment */ FT_EXPORT( FT_Error ) FTC_Manager_RegisterCache( FTC_Manager manager, FTC_CacheClass clazz, FTC_Cache *acache ); /* */ #define FTC_SCALER_COMPARE( a, b ) \ ( (a)->face_id == (b)->face_id && \ (a)->width == (b)->width && \ (a)->height == (b)->height && \ ((a)->pixel != 0) == ((b)->pixel != 0) && \ ( (a)->pixel || \ ( (a)->x_res == (b)->x_res && \ (a)->y_res == (b)->y_res ) ) ) #define FTC_SCALER_HASH( q ) \ ( FTC_FACE_ID_HASH( (q)->face_id ) + \ (q)->width + (q)->height*7 + \ ( (q)->pixel ? 0 : ( (q)->x_res*33 ^ (q)->y_res*61 ) ) ) /* */ FT_END_HEADER #endif /* __FTCMANAG_H__ */ /* END */ --- NEW FILE: ftccmap.h --- /***************************************************************************/ /* */ /* ftccmap.h */ /* */ /* FreeType charmap cache (specification). */ /* */ /* Copyright 2000-2001, 2003 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. */ /* */ /***************************************************************************/ #ifndef __FTCCMAP_H__ #define __FTCCMAP_H__ #include <ft2build.h> #include FT_CACHE_H FT_BEGIN_HEADER /*************************************************************************/ /* */ /* <Section> */ /* cache_subsystem */ /* */ /*************************************************************************/ /*************************************************************************/ /* */ /* @type: */ /* FTC_CMapCache */ /* */ /* @description: */ /* An opaque handle used to manager a charmap cache. This cache is */ /* to hold character codes -> glyph indices mappings. */ /* */ typedef struct FTC_CMapCacheRec_* FTC_CMapCache; /*************************************************************************/ /* */ /* @type: */ /* FTC_CMapDesc */ /* */ /* @description: */ /* A handle to an @FTC_CMapDescRec structure used to describe a given */ /* charmap in a charmap cache. */ /* */ /* Each @FTC_CMapDesc describes which charmap (of which @FTC_FaceID) */ /* we want to use in @FTC_CMapCache_Lookup. */ /* */ typedef struct FTC_CMapDescRec_* FTC_CMapDesc; /*************************************************************************/ /* */ /* @enum: */ /* FTC_CMapType */ /* */ /* @description: */ /* The list of valid @FTC_CMapDesc types. They indicate how we want */ /* to address a charmap within an @FTC_FaceID. */ /* */ /* @values: */ /* FTC_CMAP_BY_INDEX :: */ /* Address a charmap by its index in the corresponding @FT_Face. */ /* */ /* FTC_CMAP_BY_ENCODING :: */ /* Use a @FT_Face charmap that corresponds to a given encoding. */ /* */ /* FTC_CMAP_BY_ID :: */ /* Use an @FT_Face charmap that corresponds to a given */ /* (platform,encoding) ID. See @FTC_CMapIdRec. */ /* */ typedef enum FTC_CMapType_ { FTC_CMAP_BY_INDEX = 0, FTC_CMAP_BY_ENCODING = 1, FTC_CMAP_BY_ID = 2 } FTC_CMapType; /*************************************************************************/ /* */ /* @struct: */ /* FTC_CMapIdRec */ /* */ /* @description: */ /* A short structure to identify a charmap by a (platform,encoding) */ /* pair of values. */ /* */ /* @fields: */ /* platform :: The platform ID. */ /* */ /* encoding :: The encoding ID. */ /* */ typedef struct FTC_CMapIdRec_ { FT_UInt platform; FT_UInt encoding; } FTC_CMapIdRec; /*************************************************************************/ /* */ /* @struct: */ /* FTC_CMapDescRec */ /* */ /* @description: */ /* A structure to describe a given charmap to @FTC_CMapCache. */ /* */ /* @fields: */ /* face_id :: @FTC_FaceID of the face this charmap belongs to. */ /* */ /* type :: The type of charmap, see @FTC_CMapType. */ /* */ /* u.index :: For @FTC_CMAP_BY_INDEX types, this is the charmap */ /* index (within a @FT_Face) we want to use. */ /* */ /* u.encoding :: For @FTC_CMAP_BY_ENCODING types, this is the charmap */ /* encoding we want to use. see @FT_Encoding. */ /* */ /* u.id :: For @FTC_CMAP_BY_ID types, this is the */ /* (platform,encoding) pair we want to use. see */ /* @FTC_CMapIdRec and @FT_CharMapRec. */ /* */ typedef struct FTC_CMapDescRec_ { FTC_FaceID face_id; FTC_CMapType type; union { FT_UInt index; FT_Encoding encoding; FTC_CMapIdRec id; } u; } FTC_CMapDescRec; /*************************************************************************/ /* */ /* @function: */ /* FTC_CMapCache_New */ /* */ /* @description: */ /* Creates a new charmap cache. */ /* */ /* @input: */ /* manager :: A handle to the cache manager. */ /* */ /* @output: */ /* acache :: A new cache handle. NULL in case of error. */ /* */ /* @return: */ /* FreeType error code. 0 means success. */ /* */ /* @note: */ /* Like all other caches, this one will be destroyed with the cache */ /* manager. */ /* */ FT_EXPORT( FT_Error ) FTC_CMapCache_New( FTC_Manager manager, FTC_CMapCache *acache ); /*************************************************************************/ /* */ /* @function: */ /* FTC_CMapCache_Lookup */ /* */ /* @description: */ /* Translates a character code into a glyph index, using the charmap */ /* cache. */ /* */ /* @input: */ /* cache :: A charmap cache handle. */ /* */ /* cmap_desc :: A charmap descriptor handle. */ /* */ /* char_code :: The character code (in the corresponding charmap). */ /* */ /* @return: */ /* Glyph index. 0 means "no glyph". */ /* */ /* @note: */ /* This function doesn't return @FTC_Node handles, since there is no */ /* real use for them with typical uses of charmaps. */ /* */ FT_EXPORT( FT_UInt ) FTC_CMapCache_Lookup( FTC_CMapCache cache, FTC_CMapDesc cmap_desc, FT_UInt32 char_code ); /* */ FT_END_HEADER #endif /* __FTCCMAP_H__ */ /* END */ --- NEW FILE: ftcsbits.h --- /***************************************************************************/ /* */ /* ftcsbits.h */ /* */ /* A small-bitmap cache (specification). */ /* */ /* Copyright 2000-2001, 2002, 2003 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. */ /* */ /***************************************************************************/ #ifndef __FTCSBITS_H__ #define __FTCSBITS_H__ #include <ft2build.h> #include FT_CACHE_H #include FT_CACHE_INTERNAL_GLYPH_H FT_BEGIN_HEADER #define FTC_SBIT_ITEMS_PER_NODE 16 typedef struct FTC_SNodeRec_ { FTC_GNodeRec gnode; FT_UInt count; FTC_SBitRec sbits[FTC_SBIT_ITEMS_PER_NODE]; } FTC_SNodeRec, *FTC_SNode; #define FTC_SNODE( x ) ( (FTC_SNode)( x ) ) #define FTC_SNODE_GINDEX( x ) FTC_GNODE( x )->gindex #define FTC_SNODE_FAMILY( x ) FTC_GNODE( x )->family typedef FT_UInt (*FTC_SFamily_GetCountFunc)( FTC_Family family, FTC_Manager manager ); typedef FT_Error (*FTC_SFamily_LoadGlyphFunc)( FTC_Family family, FT_UInt gindex, FTC_Manager manager, FT_Face *aface ); typedef struct FTC_SFamilyClassRec_ { FTC_MruListClassRec clazz; FTC_SFamily_GetCountFunc family_get_count; FTC_SFamily_LoadGlyphFunc family_load_glyph; } FTC_SFamilyClassRec; typedef const FTC_SFamilyClassRec* FTC_SFamilyClass; #define FTC_SFAMILY_CLASS( x ) ((FTC_SFamilyClass)(x)) #define FTC_CACHE__SFAMILY_CLASS( x ) \ FTC_SFAMILY_CLASS( FTC_CACHE__GCACHE_CLASS( x )->family_class ) FT_EXPORT( void ) FTC_SNode_Free( FTC_SNode snode, FTC_Cache cache ); FT_EXPORT( FT_Error ) FTC_SNode_New( FTC_SNode *psnode, FTC_GQuery gquery, FTC_Cache cache ); FT_EXPORT( FT_ULong ) FTC_SNode_Weight( FTC_SNode inode ); FT_EXPORT( FT_Bool ) FTC_SNode_Compare( FTC_SNode snode, FTC_GQuery gquery, FTC_Cache cache ); /* */ FT_END_HEADER #endif /* __FTCSBITS_H__ */ /* END */ --- NEW FILE: ftccache.h --- /***************************************************************************/ /* */ /* ftccache.h */ /* */ /* FreeType internal cache interface (specification). */ /* */ /* Copyright 2000-2001, 2002, 2003, 2004, 2005 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. */ /* */ /***************************************************************************/ #ifndef __FTCCACHE_H__ #define __FTCCACHE_H__ #include FT_CACHE_INTERNAL_MRU_H FT_BEGIN_HEADER /* handle to cache object */ typedef struct FTC_CacheRec_* FTC_Cache; /* handle to cache class */ typedef const struct FTC_CacheClassRec_* FTC_CacheClass; /*************************************************************************/ /*************************************************************************/ /***** *****/ /***** CACHE NODE DEFINITIONS *****/ /***** *****/ /*************************************************************************/ /*************************************************************************/ /*************************************************************************/ /* */ /* Each cache controls one or more cache nodes. Each node is part of */ /* the global_lru list of the manager. Its `data' field however is used */ /* as a reference count for now. */ /* */ /* A node can be anything, depending on the type of information held by */ /* the cache. It can be an individual glyph image, a set of bitmaps */ /* glyphs for a given size, some metrics, etc. */ /* */ /*************************************************************************/ /* structure size should be 20 bytes on 32-bits machines */ typedef struct FTC_NodeRec_ { FTC_MruNodeRec mru; /* circular mru list pointer */ FTC_Node link; /* used for hashing */ FT_UInt32 hash; /* used for hashing too */ FT_UShort cache_index; /* index of cache the node belongs to */ FT_Short ref_count; /* reference count for this node */ } FTC_NodeRec; #define FTC_NODE( x ) ( (FTC_Node)(x) ) #define FTC_NODE_P( x ) ( (FTC_Node*)(x) ) #define FTC_NODE__NEXT(x) FTC_NODE( (x)->mru.next ) #define FTC_NODE__PREV(x) FTC_NODE( (x)->mru.prev ) /*************************************************************************/ /* */ /* These functions are exported so that they can be called from */ /* user-provided cache classes; otherwise, they are really part of the */ /* cache sub-system internals. */ /* */ /* reserved for manager's use */ FT_EXPORT( void ) ftc_node_destroy( FTC_Node node, FTC_Manager manager ); /*************************************************************************/ /*************************************************************************/ /***** *****/ /***** CACHE DEFINITIONS *****/ /***** *****/ /*************************************************************************/ /*************************************************************************/ /* initialize a new cache node */ typedef FT_Error (*FTC_Node_NewFunc)( FTC_Node *pnode, FT_Pointer query, FTC_Cache cache ); typedef FT_ULong (*FTC_Node_WeightFunc)( FTC_Node node, FTC_Cache cache ); /* compare a node to a given key pair */ typedef FT_Bool (*FTC_Node_CompareFunc)( FTC_Node node, FT_Pointer key, FTC_Cache cache ); typedef void (*FTC_Node_FreeFunc)( FTC_Node node, FTC_Cache cache ); typedef FT_Error (*FTC_Cache_InitFunc)( FTC_Cache cache ); typedef void (*FTC_Cache_DoneFunc)( FTC_Cache cache ); typedef struct FTC_CacheClassRec_ { FTC_Node_NewFunc node_new; FTC_Node_WeightFunc node_weight; FTC_Node_CompareFunc node_compare; FTC_Node_CompareFunc node_remove_faceid; FTC_Node_FreeFunc node_free; FT_UInt cache_size; FTC_Cache_InitFunc cache_init; FTC_Cache_DoneFunc cache_done; } FTC_CacheClassRec; /* each cache really implements a dynamic hash table to manage its nodes */ typedef struct FTC_CacheRec_ { FT_UFast p; FT_UFast mask; FT_Long slack; FTC_Node* buckets; FTC_CacheClassRec clazz; /* local copy, for speed */ FTC_Manager manager; FT_Memory memory; FT_UInt index; /* in manager's table */ FTC_CacheClass org_class; /* original class pointer */ } FTC_CacheRec; #define FTC_CACHE( x ) ( (FTC_Cache)(x) ) #define FTC_CACHE_P( x ) ( (FTC_Cache*)(x) ) /* default cache initialize */ FT_EXPORT( FT_Error ) FTC_Cache_Init( FTC_Cache cache ); /* default cache finalizer */ FT_EXPORT( void ) FTC_Cache_Done( FTC_Cache cache ); /* Call this function to lookup the cache. If no corresponding * node is found, a new one is automatically created. This function * is capable of flushing the cache adequately to make room for the * new cache object. */ FT_EXPORT( FT_Error ) FTC_Cache_Lookup( FTC_Cache cache, FT_UInt32 hash, FT_Pointer query, FTC_Node *anode ); FT_EXPORT( FT_Error ) FTC_Cache_NewNode( FTC_Cache cache, FT_UInt32 hash, FT_Pointer query, FTC_Node *anode ); /* Remove all nodes that relate to a given face_id. This is useful * when un-installing fonts. Note that if a cache node relates to * the face_id, but is locked (i.e., has 'ref_count > 0'), the node * will _not_ be destroyed, but its internal face_id reference will * be modified. * * The final result will be that the node will never come back * in further lookup requests, and will be flushed on demand from * the cache normally when its reference count reaches 0. */ FT_EXPORT( void ) FTC_Cache_RemoveFaceID( FTC_Cache cache, FTC_FaceID face_id ); #ifdef FTC_INLINE #define FTC_CACHE_LOOKUP_CMP( cache, nodecmp, hash, query, node, error ) \ FT_BEGIN_STMNT \ FTC_Node *_bucket, *_pnode, _node; \ FTC_Cache _cache = FTC_CACHE(cache); \ FT_UInt32 _hash = (FT_UInt32)(hash); \ FTC_Node_CompareFunc _nodcomp = (FTC_Node_CompareFunc)(nodecmp); \ FT_UInt _idx; \ \ \ error = 0; \ node = NULL; \ _idx = _hash & _cache->mask; \ if ( _idx < _cache->p ) \ _idx = _hash & ( _cache->mask*2 + 1 ); \ \ _bucket = _pnode = _cache->buckets + _idx; \ for (;;) \ { \ _node = *_pnode; \ if ( _node == NULL ) \ goto _NewNode; \ \ if ( _node->hash == _hash && _nodcomp( _node, query, _cache ) ) \ break; \ \ _pnode = &_node->link; \ } \ \ if ( _node != *_bucket ) \ { \ *_pnode = _node->link; \ _node->link = *_bucket; \ *_bucket = _node; \ } \ \ { \ FTC_Manager _manager = _cache->manager; \ \ \ if ( _node != _manager->nodes_list ) \ FTC_MruNode_Up( (FTC_MruNode*)&_manager->nodes_list, \ (FTC_MruNode)_node ); \ } \ goto _Ok; \ \ _NewNode: \ error = FTC_Cache_NewNode( _cache, _hash, query, &_node ); \ \ _Ok: \ _pnode = (FTC_Node*)(void*)&(node); \ *_pnode = _node; \ FT_END_STMNT #else /* !FTC_INLINE */ #define FTC_CACHE_LOOKUP_CMP( cache, nodecmp, hash, query, node, error ) \ FT_BEGIN_STMNT \ error = FTC_Cache_Lookup( FTC_CACHE( cache ), hash, query, \ (FTC_Node*)&(node) ); \ FT_END_STMNT #endif /* !FTC_INLINE */ /* * This macro, together with FTC_CACHE_TRYLOOP_END, defines a retry * loop to flush the cache repeatedly in case of memory overflows. * * It is used when creating a new cache node, or within a lookup * that needs to allocate data (e.g., the sbit cache lookup). * * Example: * * { * FTC_CACHE_TRYLOOP( cache ) * error = load_data( ... ); * FTC_CACHE_TRYLOOP_END() * } * */ #define FTC_CACHE_TRYLOOP( cache ) \ { \ FTC_Manager _try_manager = FTC_CACHE( cache )->manager; \ FT_UInt _try_count = 4; \ \ \ for (;;) \ { \ FT_UInt _try_done; #define FTC_CACHE_TRYLOOP_END() \ if ( !error || error != FT_Err_Out_Of_Memory ) \ break; \ \ _try_done = FTC_Manager_FlushN( _try_manager, _try_count ); \ if ( _try_done == 0 ) \ break; \ \ if ( _try_done == _try_count ) \ { \ _try_count *= 2; \ if ( _try_count < _try_done || \ _try_count > _try_manager->num_nodes ) \ _try_count = _try_manager->num_nodes; \ } \ } \ } /* */ FT_END_HEADER #endif /* __FTCCACHE_H__ */ /* END */ --- NEW FILE: ftcmru.h --- /***************************************************************************/ /* */ /* ftcmru.h */ /* */ /* Simple MRU list-cache (specification). */ /* */ /* Copyright 2000-2001, 2003, 2004, 2005 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. */ /* */ /***************************************************************************/ /*************************************************************************/ /* */ /* An MRU is a list that cannot hold more than a certain number of */ /* elements (`max_elements'). All elements in the list are sorted in */ /* least-recently-used order, i.e., the `oldest' element is at the tail */ /* of the list. */ /* */ /* When doing a lookup (either through `Lookup()' or `Lookup_Node()'), */ /* the list is searched for an element with the corresponding key. If */ /* it is found, the element is moved to the head of the list and is */ /* returned. */ /* */ /* If no corresponding element is found, the lookup routine will try to */ /* obtain a new element with the relevant key. If the list is already */ /* full, the oldest element from the list is discarded and replaced by a */ /* new one; a new element is added to the list otherwise. */ /* */ /* Note that it is possible to pre-allocate the element list nodes. */ /* This is handy if `max_elements' is sufficiently small, as it saves */ /* allocations/releases during the lookup process. */ /* */ /*************************************************************************/ #ifndef __FTCMRU_H__ #define __FTCMRU_H__ #include <ft2build.h> #include FT_FREETYPE_H #ifdef FREETYPE_H #error "freetype.h of FreeType 1 has been loaded!" #error "Please fix the directory search order for header files" #error "so that freetype.h of FreeType 2 is found first." #endif #define xxFT_DEBUG_ERROR #define FTC_INLINE FT_BEGIN_HEADER typedef struct FTC_MruNodeRec_* FTC_MruNode; typedef struct FTC_MruNodeRec_ { FTC_MruNode next; FTC_MruNode prev; } FTC_MruNodeRec; FT_EXPORT( void ) FTC_MruNode_Prepend( FTC_MruNode *plist, FTC_MruNode node ); FT_EXPORT( void ) FTC_MruNode_Up( FTC_MruNode *plist, FTC_MruNode node ); FT_EXPORT( void ) FTC_MruNode_Remove( FTC_MruNode *plist, FTC_MruNode node ); typedef struct FTC_MruListRec_* FTC_MruList; typedef struct FTC_MruListClassRec_ const * FTC_MruListClass; typedef FT_Bool (*FTC_MruNode_CompareFunc)( FTC_MruNode node, FT_Pointer key ); typedef FT_Error (*FTC_MruNode_InitFunc)( FTC_MruNode node, FT_Pointer key, FT_Pointer data ); typedef FT_Error (*FTC_MruNode_ResetFunc)( FTC_MruNode node, FT_Pointer key, FT_Pointer data ); typedef void (*FTC_MruNode_DoneFunc)( FTC_MruNode node, FT_Pointer data ); typedef struct FTC_MruListClassRec_ { FT_UInt node_size; FTC_MruNode_CompareFunc node_compare; FTC_MruNode_InitFunc node_init; FTC_MruNode_ResetFunc node_reset; FTC_MruNode_DoneFunc node_done; } FTC_MruListClassRec; typedef struct FTC_MruListRec_ { FT_UInt num_nodes; FT_UInt max_nodes; FTC_MruNode nodes; FT_Pointer data; FTC_MruListClassRec clazz; FT_Memory memory; } FTC_MruListRec; FT_EXPORT( void ) FTC_MruList_Init( FTC_MruList list, FTC_MruListClass clazz, FT_UInt max_nodes, FT_Pointer data, FT_Memory memory ); FT_EXPORT( void ) FTC_MruList_Reset( FTC_MruList list ); FT_EXPORT( void ) FTC_MruList_Done( FTC_MruList list ); FT_EXPORT( FTC_MruNode ) FTC_MruList_Find( FTC_MruList list, FT_Pointer key ); FT_EXPORT( FT_Error ) FTC_MruList_New( FTC_MruList list, FT_Pointer key, FTC_MruNode *anode ); FT_EXPORT( FT_Error ) FTC_MruList_Lookup( FTC_MruList list, FT_Pointer key, FTC_MruNode *pnode ); FT_EXPORT( void ) FTC_MruList_Remove( FTC_MruList list, FTC_MruNode node ); FT_EXPORT( void ) FTC_MruList_RemoveSelection( FTC_MruList list, FTC_MruNode_CompareFunc selection, FT_Pointer key ); #ifdef FTC_INLINE #define FTC_MRULIST_LOOKUP_CMP( list, key, compare, node, error ) \ FT_BEGIN_STMNT \ FTC_MruNode* _pfirst = &(list)->nodes; \ FTC_MruNode_CompareFunc _compare = (FTC_MruNode_CompareFunc)(compare); \ FTC_MruNode _first, _node, *_pnode; \ \ \ error = 0; \ _first = *(_pfirst); \ _node = NULL; \ \ if ( _first ) \ { \ _node = _first; \ do \ { \ if ( _compare( _node, (key) ) ) \ { \ if ( _node != _first ) \ FTC_MruNode_Up( _pfirst, _node ); \ \ _pnode = (FTC_MruNode*)(void*)&(node); \ *_pnode = _node; \ goto _MruOk; \ } \ _node = _node->next; \ \ } while ( _node != _first) ; \ } \ \ error = FTC_MruList_New( (list), (key), (FTC_MruNode*)(void*)&(node) ); \ _MruOk: \ ; \ FT_END_STMNT #define FTC_MRULIST_LOOKUP( list, key, node, error ) \ FTC_MRULIST_LOOKUP_CMP( list, key, (list)->clazz.node_compare, node, error ) #else /* !FTC_INLINE */ #define FTC_MRULIST_LOOKUP( list, key, node, error ) \ error = FTC_MruList_Lookup( (list), (key), (FTC_MruNode*)&(node) ) #endif /* !FTC_INLINE */ #define FTC_MRULIST_LOOP( list, node ) \ FT_BEGIN_STMNT \ FTC_MruNode _first = (list)->nodes; \ \ \ if ( _first ) \ { \ FTC_MruNode _node = _first; \ \ \ do \ { \ *(FTC_MruNode*)&(node) = _node; #define FTC_MRULIST_LOOP_END() \ _node = _node->next; \ \ } while ( _node != _first ); \ } \ FT_END_STMNT /* */ FT_END_HEADER #endif /* __FTCMRU_H__ */ /* END */ --- NEW FILE: ftcglyph.h --- /***************************************************************************/ /* */ /* ftcglyph.h */ /* */ /* FreeType abstract glyph cache (specification). */ /* */ /* Copyright 2000-2001, 2003, 2004 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. */ /* */ /***************************************************************************/ /* * * FTC_GCache is an _abstract_ cache object optimized to store glyph * data. It works as follows: * * - It manages FTC_GNode objects. Each one of them can hold one or more * glyph `items'. Item types are not specified in the FTC_GCache but * in classes that extend it. * * - Glyph attributes, like face ID, character size, render mode, etc., * can be grouped into abstract `glyph families'. This avoids storing * the attributes within the FTC_GCache, since it is likely that many * FTC_GNodes will belong to the same family in typical uses. * * - Each FTC_GNode is thus an FTC_Node with two additional fields: * * * gindex: A glyph index, or the first index in a glyph range. * * family: A pointer to a glyph `family'. * * - Family types are not fully specific in the FTC_Family type, but * by classes that extend it. * * Note that both FTC_ImageCache and FTC_SBitCache extend FTC_GCache. * They share an FTC_Family sub-class called FTC_BasicFamily which is * used to store the following data: face ID, pixel/point sizes, load * flags. For more details see the file `src/cache/ftcbasic.c'. * * Client applications can extend FTC_GNode with their own FTC_GNode * and FTC_Family sub-classes to implement more complex caches (e.g., * handling automatic synthesis, like obliquing & emboldening, colored * glyphs, etc.). * * See also the FTC_ICache & FTC_SCache classes in `ftcimage.h' and * `ftcsbits.h', which both extend FTC_GCache with additional * optimizations. * * A typical FTC_GCache implementation must provide at least the * following: * * - FTC_GNode sub-class, e.g. MyNode, with relevant methods: * my_node_new (must call FTC_GNode_Init) * my_node_free (must call FTC_GNode_Done) * my_node_compare (must call FTC_GNode_Compare) * my_node_remove_faceid (must call ftc_gnode_unselect in case * of match) * * - FTC_Family sub-class, e.g. MyFamily, with relevant methods: * my_family_compare * my_family_init * my_family_reset (optional) * my_family_done * * - FTC_GQuery sub-class, e.g. MyQuery, to hold cache-specific query * data. * * - Constant structures for a FTC_GNodeClass. * * - MyCacheNew() can be implemented easily as a call to the convenience * function FTC_GCache_New. * * - MyCacheLookup with a call to FTC_GCache_Lookup. This function will * automatically: * * - Search for the corresponding family in the cache, or create * a new one if necessary. Put it in FTC_GQUERY(myquery).family * * - Call FTC_Cache_Lookup. * * If it returns NULL, you should create a new node, then call * ftc_cache_add as usual. */ /*************************************************************************/ /* */ /* Important: The functions defined in this file are only used to */ /* implement an abstract glyph cache class. You need to */ /* provide additional logic to implement a complete cache. */ /* */ /*************************************************************************/ /*************************************************************************/ /*************************************************************************/ /*************************************************************************/ /*************************************************************************/ /*************************************************************************/ /********* *********/ /********* WARNING, THIS IS BETA CODE. *********/ /********* *********/ /*************************************************************************/ /*************************************************************************/ /*************************************************************************/ /*************************************************************************/ /*************************************************************************/ #ifndef __FTCGLYPH_H__ #define __FTCGLYPH_H__ #include <ft2build.h> #include FT_CACHE_INTERNAL_MANAGER_H FT_BEGIN_HEADER /* * We can group glyphs into `families'. Each family correspond to a * given face ID, character size, transform, etc. * * Families are implemented as MRU list nodes. They are * reference-counted. */ typedef struct FTC_FamilyRec_ { FTC_MruNodeRec mrunode; FT_UInt num_nodes; /* current number of nodes in this family */ FTC_Cache cache; FTC_MruListClass clazz; } FTC_FamilyRec, *FTC_Family; #define FTC_FAMILY(x) ( (FTC_Family)(x) ) #define FTC_FAMILY_P(x) ( (FTC_Family*)(x) ) typedef struct FTC_GNodeRec_ { FTC_NodeRec node; FTC_Family family; FT_UInt gindex; } FTC_GNodeRec, *FTC_GNode; #define FTC_GNODE( x ) ( (FTC_GNode)(x) ) #define FTC_GNODE_P( x ) ( (FTC_GNode*)(x) ) typedef struct FTC_GQueryRec_ { FT_UInt gindex; FTC_Family family; } FTC_GQueryRec, *FTC_GQuery; #define FTC_GQUERY( x ) ( (FTC_GQuery)(x) ) /*************************************************************************/ /* */ /* These functions are exported so that they can be called from */ /* user-provided cache classes; otherwise, they are really part of the */ /* cache sub-system internals. */ /* */ /* must be called by derived FTC_Node_InitFunc routines */ FT_EXPORT( void ) FTC_GNode_Init( FTC_GNode node, FT_UInt gindex, /* glyph index for node */ FTC_Family family ); /* returns TRUE iff the query's glyph index correspond to the node; */ /* this assumes that the "family" and "hash" fields of the query are */ /* already correctly set */ FT_EXPORT( FT_Bool ) FTC_GNode_Compare( FTC_GNode gnode, FTC_GQuery gquery ); /* call this function to clear a node's family -- this is necessary */ /* to implement the `node_remove_faceid' cache method correctly */ FT_EXPORT( void ) FTC_GNode_UnselectFamily( FTC_GNode gnode, FTC_Cache cache ); /* must be called by derived FTC_Node_DoneFunc routines */ FT_EXPORT( void ) FTC_GNode_Done( FTC_GNode node, FTC_Cache cache ); FT_EXPORT( void ) FTC_Family_Init( FTC_Family family, FTC_Cache cache ); typedef struct FTC_GCacheRec_ { FTC_C... [truncated message content] |
|
From: Ehud S. <esh...@us...> - 2006-04-21 16:13:33
|
Update of /cvsroot/roadmap/roadmap_editor/src/freetype/src/cid In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv17640/cid Log Message: Directory /cvsroot/roadmap/roadmap_editor/src/freetype/src/cid added to the repository |
|
From: Ehud S. <esh...@us...> - 2006-04-21 16:13:33
|
Update of /cvsroot/roadmap/roadmap_editor/src/freetype/src/lzw In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv17640/lzw Log Message: Directory /cvsroot/roadmap/roadmap_editor/src/freetype/src/lzw added to the repository |
|
From: Ehud S. <esh...@us...> - 2006-04-21 16:13:32
|
Update of /cvsroot/roadmap/roadmap_editor/src/freetype/src/gzip In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv17640/gzip Log Message: Directory /cvsroot/roadmap/roadmap_editor/src/freetype/src/gzip added to the repository |
|
From: Ehud S. <esh...@us...> - 2006-04-21 16:13:32
|
Update of /cvsroot/roadmap/roadmap_editor/src/freetype/src/cff In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv17640/cff Log Message: Directory /cvsroot/roadmap/roadmap_editor/src/freetype/src/cff added to the repository |
|
From: Ehud S. <esh...@us...> - 2006-04-21 16:13:32
|
Update of /cvsroot/roadmap/roadmap_editor/src/freetype/src/bdf In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv17640/bdf Log Message: Directory /cvsroot/roadmap/roadmap_editor/src/freetype/src/bdf added to the repository |
|
From: Ehud S. <esh...@us...> - 2006-04-21 16:13:32
|
Update of /cvsroot/roadmap/roadmap_editor/src/freetype/src/cache In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv17640/cache Log Message: Directory /cvsroot/roadmap/roadmap_editor/src/freetype/src/cache added to the repository |
|
From: Ehud S. <esh...@us...> - 2006-04-21 16:13:32
|
Update of /cvsroot/roadmap/roadmap_editor/src/freetype/src/base In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv17640/base Log Message: Directory /cvsroot/roadmap/roadmap_editor/src/freetype/src/base added to the repository |
|
From: Ehud S. <esh...@us...> - 2006-04-21 16:13:32
|
Update of /cvsroot/roadmap/roadmap_editor/src/freetype/src/pfr In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv17640/pfr Log Message: Directory /cvsroot/roadmap/roadmap_editor/src/freetype/src/pfr added to the repository |
|
From: Ehud S. <esh...@us...> - 2006-04-21 16:13:32
|
Update of /cvsroot/roadmap/roadmap_editor/src/freetype/src/pcf In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv17640/pcf Log Message: Directory /cvsroot/roadmap/roadmap_editor/src/freetype/src/pcf added to the repository |