📄 ftobjs.c
字号:
if ( new_max > loader->max_contours ) { new_max = ( new_max + 3 ) & -4; if ( REALLOC_ARRAY( base->contours, base->n_contours, new_max, FT_Short ) ) goto Exit; adjust = 1; loader->max_contours = new_max; } if ( adjust ) FT_GlyphLoader_Adjust_Points( loader ); Exit: return error; } /* Ensure that we can add `n_subglyphs' to our glyph. this function */ /* reallocates its subglyphs table if necessary. Note that it DOES */ /* NOT change the number of subglyphs within the loader! */ /* */ FT_BASE_DEF( FT_Error ) FT_GlyphLoader_Check_Subglyphs( FT_GlyphLoader* loader, FT_UInt n_subs ) { FT_Memory memory = loader->memory; FT_Error error = FT_Err_Ok; FT_UInt new_max; FT_GlyphLoad* base = &loader->base; FT_GlyphLoad* current = &loader->current; new_max = base->num_subglyphs + current->num_subglyphs + n_subs; if ( new_max > loader->max_subglyphs ) { new_max = ( new_max + 1 ) & -2; if ( REALLOC_ARRAY( base->subglyphs, base->num_subglyphs, new_max, FT_SubGlyph ) ) goto Exit; loader->max_subglyphs = new_max; FT_GlyphLoader_Adjust_Subglyphs( loader ); } Exit: return error; } /* prepare loader for the addition of a new glyph on top of the base one */ FT_BASE_DEF( void ) FT_GlyphLoader_Prepare( FT_GlyphLoader* loader ) { FT_GlyphLoad* current = &loader->current; current->outline.n_points = 0; current->outline.n_contours = 0; current->num_subglyphs = 0; FT_GlyphLoader_Adjust_Points ( loader ); FT_GlyphLoader_Adjust_Subglyphs( loader ); } /* add current glyph to the base image - and prepare for another */ FT_BASE_DEF( void ) FT_GlyphLoader_Add( FT_GlyphLoader* loader ) { FT_GlyphLoad* base = &loader->base; FT_GlyphLoad* current = &loader->current; FT_UInt n_curr_contours = current->outline.n_contours; FT_UInt n_base_points = base->outline.n_points; FT_UInt n; base->outline.n_points += current->outline.n_points; base->outline.n_contours += current->outline.n_contours; base->num_subglyphs += current->num_subglyphs; /* adjust contours count in newest outline */ for ( n = 0; n < n_curr_contours; n++ ) current->outline.contours[n] += n_base_points; /* prepare for another new glyph image */ FT_GlyphLoader_Prepare( loader ); } FT_BASE_DEF( FT_Error ) FT_GlyphLoader_Copy_Points( FT_GlyphLoader* target, FT_GlyphLoader* source ) { FT_Error error; FT_UInt num_points = source->base.outline.n_points; FT_UInt num_contours = source->base.outline.n_contours; error = FT_GlyphLoader_Check_Points( target, num_points, num_contours ); if ( !error ) { FT_Outline* out = &target->base.outline; FT_Outline* in = &source->base.outline; MEM_Copy( out->points, in->points, num_points * sizeof ( FT_Vector ) ); MEM_Copy( out->tags, in->tags, num_points * sizeof ( char ) ); MEM_Copy( out->contours, in->contours, num_contours * sizeof ( short ) ); /* do we need to copy the extra points? */ if ( target->use_extra && source->use_extra ) MEM_Copy( target->base.extra_points, source->base.extra_points, num_points * sizeof ( FT_Vector ) ); out->n_points = num_points; out->n_contours = num_contours; FT_GlyphLoader_Adjust_Points( target ); } return error; } /*************************************************************************/ /*************************************************************************/ /*************************************************************************/ /**** ****/ /**** ****/ /**** 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 ( ALLOC( internal, sizeof ( *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; } static void ft_glyphslot_clear( FT_GlyphSlot slot ) { /* free bitmap if needed */ if ( slot->flags & ft_glyph_own_bitmap ) { FT_Memory memory = FT_FACE_MEMORY( slot->face ); FREE( slot->bitmap.buffer ); slot->flags &= ~ft_glyph_own_bitmap; } /* clear all public fields in the glyph slot */ MEM_Set( &slot->metrics, 0, sizeof ( slot->metrics ) ); MEM_Set( &slot->outline, 0, sizeof ( slot->outline ) ); MEM_Set( &slot->bitmap, 0, sizeof ( slot->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; } 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 */ if ( slot->flags & ft_glyph_own_bitmap ) FREE( slot->bitmap.buffer ); /* free glyph loader */ if ( FT_DRIVER_USES_OUTLINES( driver ) ) { FT_GlyphLoader_Done( slot->internal->loader ); slot->internal->loader = 0; } 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 ( !ALLOC( slot, clazz->slot_object_size ) ) { slot->face = face; error = ft_glyphslot_init( slot ); if ( error ) { ft_glyphslot_done( slot ); 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 ); 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_Int 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; /* when the flag NO_RECURSE is set, we disable hinting and scaling */ if ( load_flags & FT_LOAD_NO_RECURSE ) { /* disable scaling, hinting, and transformation */ load_flags |= FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING | FT_LOAD_IGNORE_TRANSFORM; /* disable bitmap rendering */ load_flags &= ~FT_LOAD_RENDER; } /* do we need to load the glyph through the auto-hinter? */ library = driver->root.library; hinter = library->auto_hinter; autohint = hinter && !( load_flags & ( FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING ) ) && FT_DRIVER_IS_SCALABLE(driver) && FT_DRIVER_USES_OUTLINES(driver); if ( autohint ) { if ( FT_DRIVER_HAS_HINTER( driver ) && !( load_flags & FT_LOAD_FORCE_AUTOHINT ) ) autohint = 0; } if ( autohint ) { FT_AutoHinter_Interface* hinting; hinting = (FT_AutoHinter_Interface*)hinter->clazz->module_interface; error = hinting->load_glyph( (FT_AutoHinter)hinter, slot, face->size, glyph_index, load_flags ); } else error = driver->clazz->load_glyph( slot, face->size, glyph_index, load_flags ); if ( error ) goto Exit; /* compute the advance */ if ( load_flags & FT_LOAD_VERTICAL_LAYOUT ) { slot->advance.x = 0; slot->advance.y = slot->metrics.vertAdvance; } else { slot->advance.x = slot->metrics.horiAdvance; slot->advance.y = 0; } /* compute the linear advance in 16.16 pixels */ if ( ( load_flags & FT_LOAD_LINEAR_DESIGN ) == 0 ) { FT_UInt EM = face->units_per_EM; FT_Size_Metrics* metrics = &face->size->metrics; slot->linearHoriAdvance = FT_MulDiv( slot->linearHoriAdvance, (FT_Long)metrics->x_ppem << 16, EM ); slot->linearVertAdvance = FT_MulDiv( slot->linearVertAdvance, (FT_Long)metrics->y_ppem << 16, EM ); } if ( ( load_flags & FT_LOAD_IGNORE_TRANSFORM ) == 0 ) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -