📄 ftobjs.c
字号:
/***************************************************************************//* *//* ftobjs.c *//* *//* The FreeType private base classes (body). *//* *//* 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. *//* *//***************************************************************************/#include <ft2build.h>#include FT_LIST_H#include FT_OUTLINE_H#include FT_INTERNAL_OBJECTS_H#include FT_INTERNAL_DEBUG_H#include FT_INTERNAL_STREAM_H#include FT_INTERNAL_SFNT_H /* for SFNT_Load_Table_Func */#include FT_TRUETYPE_TABLES_H#include FT_TRUETYPE_IDS_H#include FT_OUTLINE_H FT_BASE_DEF( void ) ft_validator_init( FT_Validator valid, const FT_Byte* base, const FT_Byte* limit, FT_ValidationLevel level ) { valid->base = base; valid->limit = limit; valid->level = level; valid->error = 0; } FT_BASE_DEF( FT_Int ) ft_validator_run( FT_Validator valid ) { int result; result = ft_setjmp( valid->jump_buffer ); return result; } FT_BASE_DEF( void ) ft_validator_error( FT_Validator valid, FT_Error error ) { valid->error = error; ft_longjmp( valid->jump_buffer, 1 ); } /*************************************************************************/ /*************************************************************************/ /*************************************************************************/ /**** ****/ /**** ****/ /**** S T R E A M ****/ /**** ****/ /**** ****/ /*************************************************************************/ /*************************************************************************/ /*************************************************************************/ /* create a new input stream from a FT_Open_Args structure */ /* */ static FT_Error ft_input_stream_new( FT_Library library, const FT_Open_Args* args, FT_Stream* astream ) { FT_Error error; FT_Memory memory; FT_Stream stream; if ( !library ) return FT_Err_Invalid_Library_Handle; if ( !args ) return FT_Err_Invalid_Argument; *astream = 0; memory = library->memory; if ( FT_NEW( stream ) ) goto Exit; stream->memory = memory; if ( args->flags & FT_OPEN_MEMORY ) { /* create a memory-based stream */ FT_Stream_OpenMemory( stream, (const FT_Byte*)args->memory_base, args->memory_size ); } else if ( args->flags & FT_OPEN_PATHNAME ) { /* create a normal system stream */ error = FT_Stream_Open( stream, args->pathname ); stream->pathname.pointer = args->pathname; } else if ( ( args->flags & FT_OPEN_STREAM ) && args->stream ) { /* use an existing, user-provided stream */ /* in this case, we do not need to allocate a new stream object */ /* since the caller is responsible for closing it himself */ FT_FREE( stream ); stream = args->stream; } else error = FT_Err_Invalid_Argument; if ( error ) FT_FREE( stream ); else stream->memory = memory; /* just to be certain */ *astream = stream; Exit: return error; } static void ft_input_stream_free( FT_Stream stream, FT_Int external ) { if ( stream ) { FT_Memory memory = stream->memory; FT_Stream_Close( stream ); if ( !external ) FT_FREE( stream ); } }#undef FT_COMPONENT#define FT_COMPONENT trace_objs /*************************************************************************/ /*************************************************************************/ /*************************************************************************/ /**** ****/ /**** ****/ /**** FACE, SIZE & GLYPH SLOT OBJECTS ****/ /**** ****/ /**** ****/ /*************************************************************************/ /*************************************************************************/ /*************************************************************************/ static FT_Error ft_glyphslot_init( FT_GlyphSlot slot ) { FT_Driver driver = slot->face->driver; FT_Driver_Class clazz = driver->clazz; FT_Memory memory = driver->root.memory; FT_Error error = FT_Err_Ok; FT_Slot_Internal internal; slot->library = driver->root.library; if ( FT_NEW( internal ) ) goto Exit; slot->internal = internal; if ( FT_DRIVER_USES_OUTLINES( driver ) ) error = FT_GlyphLoader_New( memory, &internal->loader ); if ( !error && clazz->init_slot ) error = clazz->init_slot( slot ); Exit: return error; } FT_BASE_DEF( void ) ft_glyphslot_free_bitmap( FT_GlyphSlot slot ) { if ( slot->internal->flags & FT_GLYPH_OWN_BITMAP ) { FT_Memory memory = FT_FACE_MEMORY( slot->face ); FT_FREE( slot->bitmap.buffer ); slot->internal->flags &= ~FT_GLYPH_OWN_BITMAP; } else { /* assume that the bitmap buffer was stolen or not */ /* allocated from the heap */ slot->bitmap.buffer = NULL; } } FT_BASE_DEF( void ) ft_glyphslot_set_bitmap( FT_GlyphSlot slot, FT_Byte* buffer ) { ft_glyphslot_free_bitmap( slot ); slot->bitmap.buffer = buffer; FT_ASSERT( (slot->internal->flags & FT_GLYPH_OWN_BITMAP) == 0 ); } FT_BASE_DEF( FT_Error ) ft_glyphslot_alloc_bitmap( FT_GlyphSlot slot, FT_ULong size ) { FT_Memory memory = FT_FACE_MEMORY( slot->face ); if ( slot->internal->flags & FT_GLYPH_OWN_BITMAP ) FT_FREE( slot->bitmap.buffer ); else slot->internal->flags |= FT_GLYPH_OWN_BITMAP; return FT_MEM_ALLOC( slot->bitmap.buffer, size ); } static void ft_glyphslot_clear( FT_GlyphSlot slot ) { /* free bitmap if needed */ ft_glyphslot_free_bitmap( slot ); /* clear all public fields in the glyph slot */ FT_ZERO( &slot->metrics ); FT_ZERO( &slot->outline ); slot->bitmap.width = 0; slot->bitmap.rows = 0; slot->bitmap.pitch = 0; slot->bitmap.pixel_mode = 0; /* don't touch 'slot->bitmap.buffer'! */ slot->bitmap_left = 0; slot->bitmap_top = 0; slot->num_subglyphs = 0; slot->subglyphs = 0; slot->control_data = 0; slot->control_len = 0; slot->other = 0; slot->format = FT_GLYPH_FORMAT_NONE; slot->linearHoriAdvance = 0; slot->linearVertAdvance = 0; } static void ft_glyphslot_done( FT_GlyphSlot slot ) { FT_Driver driver = slot->face->driver; FT_Driver_Class clazz = driver->clazz; FT_Memory memory = driver->root.memory; if ( clazz->done_slot ) clazz->done_slot( slot ); /* free bitmap buffer if needed */ ft_glyphslot_free_bitmap( slot ); /* free glyph loader */ if ( FT_DRIVER_USES_OUTLINES( driver ) ) { FT_GlyphLoader_Done( slot->internal->loader ); slot->internal->loader = 0; } FT_FREE( slot->internal ); } /* documentation is in ftobjs.h */ FT_BASE_DEF( FT_Error ) FT_New_GlyphSlot( FT_Face face, FT_GlyphSlot *aslot ) { FT_Error error; FT_Driver driver; FT_Driver_Class clazz; FT_Memory memory; FT_GlyphSlot slot; if ( !face || !aslot || !face->driver ) return FT_Err_Invalid_Argument; *aslot = 0; driver = face->driver; clazz = driver->clazz; memory = driver->root.memory; FT_TRACE4(( "FT_New_GlyphSlot: Creating new slot object\n" )); if ( !FT_ALLOC( slot, clazz->slot_object_size ) ) { slot->face = face; error = ft_glyphslot_init( slot ); if ( error ) { ft_glyphslot_done( slot ); FT_FREE( slot ); goto Exit; } *aslot = slot; } Exit: FT_TRACE4(( "FT_New_GlyphSlot: Return %d\n", error )); return error; } /* documentation is in ftobjs.h */ FT_BASE_DEF( void ) FT_Done_GlyphSlot( FT_GlyphSlot slot ) { if ( slot ) { FT_Driver driver = slot->face->driver; FT_Memory memory = driver->root.memory; FT_GlyphSlot* parent; FT_GlyphSlot cur; /* Remove slot from its parent face's list */ parent = &slot->face->glyph; cur = *parent; while ( cur ) { if ( cur == slot ) { *parent = cur->next; ft_glyphslot_done( slot ); FT_FREE( slot ); break; } cur = cur->next; } } } /* documentation is in freetype.h */ FT_EXPORT_DEF( void ) FT_Set_Transform( FT_Face face, FT_Matrix* matrix, FT_Vector* delta ) { FT_Face_Internal internal; if ( !face ) return; internal = face->internal; internal->transform_flags = 0; if ( !matrix ) { internal->transform_matrix.xx = 0x10000L; internal->transform_matrix.xy = 0; internal->transform_matrix.yx = 0; internal->transform_matrix.yy = 0x10000L; matrix = &internal->transform_matrix; } else internal->transform_matrix = *matrix; /* set transform_flags bit flag 0 if `matrix' isn't the identity */ if ( ( matrix->xy | matrix->yx ) || matrix->xx != 0x10000L || matrix->yy != 0x10000L ) internal->transform_flags |= 1; if ( !delta ) { internal->transform_delta.x = 0; internal->transform_delta.y = 0; delta = &internal->transform_delta; } else internal->transform_delta = *delta; /* set transform_flags bit flag 1 if `delta' isn't the null vector */ if ( delta->x | delta->y ) internal->transform_flags |= 2; } static FT_Renderer ft_lookup_glyph_renderer( FT_GlyphSlot slot ); /* documentation is in freetype.h */ FT_EXPORT_DEF( FT_Error ) FT_Load_Glyph( FT_Face face, FT_UInt glyph_index, FT_Int32 load_flags ) { FT_Error error; FT_Driver driver; FT_GlyphSlot slot; FT_Library library; FT_Bool autohint; FT_Module hinter; if ( !face || !face->size || !face->glyph ) return FT_Err_Invalid_Face_Handle; if ( glyph_index >= (FT_UInt)face->num_glyphs ) return FT_Err_Invalid_Argument; slot = face->glyph; ft_glyphslot_clear( slot ); driver = face->driver; /* if the flag NO_RECURSE is set, we disable hinting and scaling */ if ( load_flags & FT_LOAD_NO_RECURSE ) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -