📄 ftobjs.c
字号:
/***************************************************************************/
/* */
/* ftobjs.c */
/* */
/* The FreeType private base classes (body). */
/* */
/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
/* modified, and distributed under the terms of the FreeType project */
/* license, LICENSE.TXT. By continuing to use, modify, or distribute */
/* this file you indicate that you have read the license and */
/* understand and accept it fully. */
/* */
/***************************************************************************/
#include <ft2build.h>
#include FT_LIST_H
#include FT_OUTLINE_H
#include FT_INTERNAL_VALIDATE_H
#include FT_INTERNAL_OBJECTS_H
#include FT_INTERNAL_DEBUG_H
#include FT_INTERNAL_RFORK_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
#include FT_SERVICE_SFNT_H
#include FT_SERVICE_POSTSCRIPT_NAME_H
#include FT_SERVICE_GLYPH_DICT_H
#include FT_SERVICE_TT_CMAP_H
#include FT_SERVICE_KERNING_H
#include FT_SERVICE_TRUETYPE_ENGINE_H
#define GRID_FIT_METRICS
FT_BASE_DEF( FT_Pointer )
ft_service_list_lookup( FT_ServiceDesc service_descriptors,
const char* service_id )
{
FT_Pointer result = NULL;
FT_ServiceDesc desc = service_descriptors;
if ( desc && service_id )
{
for ( ; desc->serv_id != NULL; desc++ )
{
if ( ft_strcmp( desc->serv_id, service_id ) == 0 )
{
result = (FT_Pointer)desc->serv_data;
break;
}
}
}
return result;
}
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 = FT_Err_Ok;
}
FT_BASE_DEF( FT_Int )
ft_validator_run( FT_Validator valid )
{
/* This function doesn't work! None should call it. */
FT_UNUSED( valid );
return -1;
}
FT_BASE_DEF( void )
ft_validator_error( FT_Validator valid,
FT_Error error )
{
/* since the cast below also disables the compiler's */
/* type check, we introduce a dummy variable, which */
/* will be optimized away */
volatile jmp_buf* jump_buffer = &valid->jump_buffer;
valid->error = error;
/* throw away volatileness; use `jump_buffer' or the */
/* compiler may warn about an unused local variable */
ft_longjmp( *(jmp_buf*) jump_buffer, 1 );
}
/*************************************************************************/
/*************************************************************************/
/*************************************************************************/
/**** ****/
/**** ****/
/**** S T R E A M ****/
/**** ****/
/**** ****/
/*************************************************************************/
/*************************************************************************/
/*************************************************************************/
/* create a new input stream from an FT_Open_Args structure */
/* */
FT_BASE_DEF( FT_Error )
FT_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;
}
FT_BASE_DEF( void )
FT_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 );
FT_Error error;
if ( slot->internal->flags & FT_GLYPH_OWN_BITMAP )
FT_FREE( slot->bitmap.buffer );
else
slot->internal->flags |= FT_GLYPH_OWN_BITMAP;
(void)FT_ALLOC( slot->bitmap.buffer, size );
return error;
}
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;
/* `slot->bitmap.buffer' has been handled by ft_glyphslot_free_bitmap */
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;
slot->lsb_delta = 0;
slot->rsb_delta = 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 || !face->driver )
return FT_Err_Invalid_Argument;
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;
}
slot->next = face->glyph;
face->glyph = slot;
if ( aslot )
*aslot = slot;
}
else if ( aslot )
*aslot = 0;
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 prev;
FT_GlyphSlot cur;
/* Remove slot from its parent face's list */
prev = NULL;
cur = slot->face->glyph;
while ( cur )
{
if ( cur == slot )
{
if ( !prev )
slot->face->glyph = cur->next;
else
prev->next = cur->next;
ft_glyphslot_done( slot );
FT_FREE( slot );
break;
}
prev = cur;
cur = cur->next;
}
}
}
/* documentation is in freetype.h */
FT_EXPORT_DEF( void )
FT_Set_Transform( FT_Face face,
FT_Matrix* matrix,
FT_Vector* delta )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -