1ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/***************************************************************************/ 2ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* */ 3ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* ftadvanc.c */ 4ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* */ 5ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* Quick computation of advance widths (body). */ 6ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* */ 7e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov/* Copyright 2008, 2009, 2011, 2013, 2014 by */ 8ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* David Turner, Robert Wilhelm, and Werner Lemberg. */ 9ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* */ 10ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* This file is part of the FreeType project, and may only be used, */ 11ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* modified, and distributed under the terms of the FreeType project */ 12ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ 13ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* this file you indicate that you have read the license and */ 14ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* understand and accept it fully. */ 15ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* */ 16ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/***************************************************************************/ 17ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 18ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 19e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov#include <ft2build.h> 20e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov#include FT_INTERNAL_DEBUG_H 21ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 22e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov#include FT_ADVANCES_H 23e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov#include FT_INTERNAL_OBJECTS_H 24ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 25ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 26ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static FT_Error 27ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov _ft_face_scale_advances( FT_Face face, 28ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Fixed* advances, 29ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt count, 30ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Int32 flags ) 31ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 32ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Fixed scale; 33ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt nn; 34ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 35ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 36ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( flags & FT_LOAD_NO_SCALE ) 37ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_Err_Ok; 38ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 39ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( face->size == NULL ) 40ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_THROW( Invalid_Size_Handle ); 41ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 42ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( flags & FT_LOAD_VERTICAL_LAYOUT ) 43ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov scale = face->size->metrics.y_scale; 44ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 45ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov scale = face->size->metrics.x_scale; 46ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 47ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* this must be the same scaling as to get linear{Hori,Vert}Advance */ 48ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* (see `FT_Load_Glyph' implementation in src/base/ftobjs.c) */ 49ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 50ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for ( nn = 0; nn < count; nn++ ) 51ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov advances[nn] = FT_MulDiv( advances[nn], scale, 64 ); 52ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 53ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_Err_Ok; 54ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 55ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 56ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 57ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* at the moment, we can perform fast advance retrieval only in */ 58ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* the following cases: */ 59ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 60ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* - unscaled load */ 61ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* - unhinted load */ 62ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* - light-hinted load */ 63ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 64ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define LOAD_ADVANCE_FAST_CHECK( flags ) \ 65ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ( flags & ( FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING ) || \ 66ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_LOAD_TARGET_MODE( flags ) == FT_RENDER_MODE_LIGHT ) 67ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 68ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 69ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* documentation is in ftadvanc.h */ 70ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 71ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_EXPORT_DEF( FT_Error ) 72ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Get_Advance( FT_Face face, 73ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt gindex, 74ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Int32 flags, 75ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Fixed *padvance ) 76ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 77ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Face_GetAdvancesFunc func; 78ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 79ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 80ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !face ) 81ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_THROW( Invalid_Face_Handle ); 82ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 83e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov if ( !padvance ) 84e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov return FT_THROW( Invalid_Argument ); 85e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 86ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( gindex >= (FT_UInt)face->num_glyphs ) 87ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_THROW( Invalid_Glyph_Index ); 88ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 89ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov func = face->driver->clazz->get_advances; 90ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( func && LOAD_ADVANCE_FAST_CHECK( flags ) ) 91ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 92ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Error error; 93ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 94ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 95ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = func( face, gindex, 1, flags, padvance ); 96ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !error ) 97ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return _ft_face_scale_advances( face, padvance, 1, flags ); 98ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 99ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( FT_ERR_NEQ( error, Unimplemented_Feature ) ) 100ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return error; 101ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 102ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 103ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_Get_Advances( face, gindex, 1, flags, padvance ); 104ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 105ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 106ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 107ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* documentation is in ftadvanc.h */ 108ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 109ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_EXPORT_DEF( FT_Error ) 110ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Get_Advances( FT_Face face, 111ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt start, 112ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt count, 113ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Int32 flags, 114ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Fixed *padvances ) 115ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 116ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Face_GetAdvancesFunc func; 117ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt num, end, nn; 118ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Error error = FT_Err_Ok; 119ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 120ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 121ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !face ) 122ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_THROW( Invalid_Face_Handle ); 123ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 124e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov if ( !padvances ) 125e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov return FT_THROW( Invalid_Argument ); 126e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 127ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov num = (FT_UInt)face->num_glyphs; 128ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov end = start + count; 129ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( start >= num || end < start || end > num ) 130ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_THROW( Invalid_Glyph_Index ); 131ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 132ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( count == 0 ) 133ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_Err_Ok; 134ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 135ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov func = face->driver->clazz->get_advances; 136ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( func && LOAD_ADVANCE_FAST_CHECK( flags ) ) 137ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 138ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = func( face, start, count, flags, padvances ); 139ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !error ) 140ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return _ft_face_scale_advances( face, padvances, count, flags ); 141ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 142ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( FT_ERR_NEQ( error, Unimplemented_Feature ) ) 143ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return error; 144ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 145ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 146ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = FT_Err_Ok; 147ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 148ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( flags & FT_ADVANCE_FLAG_FAST_ONLY ) 149ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_THROW( Unimplemented_Feature ); 150ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 151ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov flags |= (FT_UInt32)FT_LOAD_ADVANCE_ONLY; 152ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for ( nn = 0; nn < count; nn++ ) 153ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 154ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = FT_Load_Glyph( face, start + nn, flags ); 155ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( error ) 156ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 157ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 158ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* scale from 26.6 to 16.16 */ 159ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov padvances[nn] = ( flags & FT_LOAD_VERTICAL_LAYOUT ) 160ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ? face->glyph->advance.y << 10 161ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov : face->glyph->advance.x << 10; 162ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 163ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 164ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return error; 165ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 166ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 167ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 168ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* END */ 169