📄 ftobjs.c
字号:
/***************************************************************************//* *//* ftobjs.c *//* *//* The FreeType private base classes (body). *//* *//* Copyright 1996-2000 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 <freetype/ftlist.h>#include <freetype/internal/ftobjs.h>#include <freetype/internal/ftdebug.h>#include <freetype/internal/ftstream.h>#include <freetype/tttables.h>#include <string.h> /* for strcmp() */ /*************************************************************************/ /*************************************************************************/ /*************************************************************************/ /**** ****/ /**** ****/ /**** M E M O R Y ****/ /**** ****/ /**** ****/ /*************************************************************************/ /*************************************************************************/ /*************************************************************************/ /*************************************************************************/ /* */ /* 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_memory /* documentation is in ftmemory.h */ FT_BASE_DEF( FT_Error ) FT_Alloc( FT_Memory memory, FT_Long size, void* *P ) { FT_Assert( P != 0 ); if ( size > 0 ) { *P = memory->alloc( memory, size ); if ( !*P ) { FT_ERROR(( "FT_Alloc:" )); FT_ERROR(( " Out of memory? (%ld requested)\n", size )); return FT_Err_Out_Of_Memory; } MEM_Set( *P, 0, size ); } else *P = NULL; FT_TRACE7(( "FT_Alloc:" )); FT_TRACE7(( " size = %ld, block = 0x%08p, ref = 0x%08p\n", size, *P, P )); return FT_Err_Ok; } /* documentation is in ftmemory.h */ FT_BASE_DEF( FT_Error ) FT_Realloc( FT_Memory memory, FT_Long current, FT_Long size, void** P ) { void* Q; FT_Assert( P != 0 ); /* if the original pointer is NULL, call FT_Alloc() */ if ( !*P ) return FT_Alloc( memory, size, P ); /* if the new block if zero-sized, clear the current one */ if ( size <= 0 ) { FT_Free( memory, P ); return FT_Err_Ok; } Q = memory->realloc( memory, current, size, *P ); if ( !Q ) goto Fail; *P = Q; return FT_Err_Ok; Fail: FT_ERROR(( "FT_Realloc:" )); FT_ERROR(( " Failed (current %ld, requested %ld)\n", current, size )); return FT_Err_Out_Of_Memory; } /* documentation is in ftmemory.h */ FT_BASE_DEF( void ) FT_Free( FT_Memory memory, void** P ) { FT_TRACE7(( "FT_Free:" )); FT_TRACE7(( " Freeing block 0x%08p, ref 0x%08p\n", P, P ? *P : (void*)0 )); if ( P && *P ) { memory->free( memory, *P ); *P = 0; } } /*************************************************************************/ /*************************************************************************/ /*************************************************************************/ /**** ****/ /**** ****/ /**** S T R E A M ****/ /**** ****/ /**** ****/ /*************************************************************************/ /*************************************************************************/ /*************************************************************************/ /*************************************************************************/ /* */ /* <Function> */ /* ft_new_input_stream */ /* */ /* <Description> */ /* Creates a new input stream object from an FT_Open_Args structure. */ /* */ /* <Note> */ /* The function expects a valid `astream' parameter. */ /* */ static FT_Error ft_new_input_stream( FT_Library library, 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 ( ALLOC( stream, sizeof ( *stream ) ) ) goto Exit; stream->memory = memory; /* now, look at the stream flags */ if ( args->flags & ft_open_memory ) { error = 0; FT_New_Memory_Stream( library, args->memory_base, args->memory_size, stream ); } else if ( args->flags & ft_open_pathname ) { error = FT_New_Stream( args->pathname, stream ); stream->pathname.pointer = args->pathname; } else if ( ( args->flags & ft_open_stream ) && args->stream ) { /* in this case, we do not need to allocate a new stream object */ /* since the caller is responsible for closing it himself */ FREE( stream ); stream = args->stream; } else error = FT_Err_Invalid_Argument; if ( error ) FREE( stream ); *astream = stream; Exit: return error; } /* documentation is in ftobjs.h */ FT_EXPORT_DEF( void ) FT_Done_Stream( FT_Stream stream ) { if ( stream && stream->close ) { stream->close( stream ); stream->close = 0; } } static void ft_done_stream( FT_Stream* astream, FT_Int external ) { FT_Stream stream = *astream; if ( stream->close ) stream->close( stream ); if ( !external ) { FT_Memory memory = stream->memory; FREE( stream ); } *astream = 0; }#undef FT_COMPONENT#define FT_COMPONENT trace_objs /*************************************************************************/ /*************************************************************************/ /*************************************************************************/ /**** ****/ /**** ****/ /**** G L Y P H L O A D E R ****/ /**** ****/ /**** ****/ /*************************************************************************/ /*************************************************************************/ /*************************************************************************/ /*************************************************************************/ /* */ /* The glyph loader is a simple object which is used to load a set of */ /* glyphs easily. It is critical for the correct loading of composites. */ /* */ /* Ideally, one can see it as a stack of abstract `glyph' objects. */ /* */ /* loader.base Is really the bottom of the stack. It describes a */ /* single glyph image made of the juxtaposition of */ /* several glyphs (those `in the stack'). */ /* */ /* loader.current Describes the top of the stack, on which a new */ /* glyph can be loaded. */ /* */ /* Rewind Clears the stack. */ /* Prepare Set up `loader.current' for addition of a new glyph */ /* image. */ /* Add Add the `current' glyph image to the `base' one, */ /* and prepare for another one. */ /* */ /* The glyph loader is now a base object. Each driver used to */ /* re-implement it in one way or the other, which wasted code and */ /* energy. */ /* */ /*************************************************************************/ /* create a new glyph loader */ FT_BASE_DEF( FT_Error ) FT_GlyphLoader_New( FT_Memory memory, FT_GlyphLoader* *aloader ) { FT_GlyphLoader* loader; FT_Error error; if ( !ALLOC( loader, sizeof ( *loader ) ) ) { loader->memory = memory; *aloader = loader; } return error; } /* rewind the glyph loader - reset counters to 0 */ FT_BASE_DEF( void ) FT_GlyphLoader_Rewind( FT_GlyphLoader* loader ) { FT_GlyphLoad* base = &loader->base; FT_GlyphLoad* current = &loader->current; base->outline.n_points = 0; base->outline.n_contours = 0; base->num_subglyphs = 0; *current = *base; } /* reset the glyph loader, frees all allocated tables */ /* and starts from zero */ FT_BASE_DEF( void ) FT_GlyphLoader_Reset( FT_GlyphLoader* loader ) { FT_Memory memory = loader->memory; FREE( loader->base.outline.points ); FREE( loader->base.outline.tags ); FREE( loader->base.outline.contours ); FREE( loader->base.extra_points ); FREE( loader->base.subglyphs ); loader->max_points = 0; loader->max_contours = 0; loader->max_subglyphs = 0; FT_GlyphLoader_Rewind( loader ); } /* delete a glyph loader */ FT_BASE_DEF( void ) FT_GlyphLoader_Done( FT_GlyphLoader* loader ) { if ( loader ) { FT_Memory memory = loader->memory; FT_GlyphLoader_Reset( loader ); FREE( loader ); } } /* re-adjust the `current' outline fields */ static void FT_GlyphLoader_Adjust_Points( FT_GlyphLoader* loader ) { FT_Outline* base = &loader->base.outline; FT_Outline* current = &loader->current.outline; current->points = base->points + base->n_points; current->tags = base->tags + base->n_points; current->contours = base->contours + base->n_contours; /* handle extra points table - if any */ if ( loader->use_extra ) loader->current.extra_points = loader->base.extra_points + base->n_points; } FT_BASE_DEF( FT_Error ) FT_GlyphLoader_Create_Extra( FT_GlyphLoader* loader ) { FT_Error error; FT_Memory memory = loader->memory; if ( !ALLOC_ARRAY( loader->base.extra_points, loader->max_points, FT_Vector ) ) { loader->use_extra = 1; FT_GlyphLoader_Adjust_Points( loader ); } return error; } /* re-adjust the `current' subglyphs field */ static void FT_GlyphLoader_Adjust_Subglyphs( FT_GlyphLoader* loader ) { FT_GlyphLoad* base = &loader->base; FT_GlyphLoad* current = &loader->current; current->subglyphs = base->subglyphs + base->num_subglyphs; } /* Ensure that we can add `n_points' and `n_contours' to our glyph. this */ /* function reallocates its outline tables if necessary. Note that it */ /* DOESN'T change the number of points within the loader! */ /* */ FT_BASE_DEF( FT_Error ) FT_GlyphLoader_Check_Points( FT_GlyphLoader* loader, FT_UInt n_points, FT_UInt n_contours ) { FT_Memory memory = loader->memory; FT_Error error = FT_Err_Ok; FT_Outline* base = &loader->base.outline; FT_Outline* current = &loader->current.outline; FT_Bool adjust = 1; FT_UInt new_max; /* check points & tags */ new_max = base->n_points + current->n_points + n_points; if ( new_max > loader->max_points ) { new_max = ( new_max + 7 ) & -8; if ( REALLOC_ARRAY( base->points, base->n_points, new_max, FT_Vector ) || REALLOC_ARRAY( base->tags, base->n_points, new_max, FT_Byte ) ) goto Exit; if ( loader->use_extra && REALLOC_ARRAY( loader->base.extra_points, base->n_points, new_max, FT_Vector ) ) goto Exit; adjust = 1; loader->max_points = new_max; } /* check contours */ new_max = base->n_contours + current->n_contours + n_contours;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -