186 lines
6.2 KiB
C
186 lines
6.2 KiB
C
/*******************************************************************
|
|
*
|
|
* ftxwidth.c 1.0
|
|
*
|
|
* Glyph Widths (and Heights) fast retrieval extension
|
|
*
|
|
* Copyright 1996-1999 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.
|
|
*
|
|
*
|
|
* This extension is used to parse the "glyf" table of a TrueType
|
|
* file in order to extract the bbox of a given range of glyphs.
|
|
*
|
|
* The bbox is then used to build font unit widths and height
|
|
* that are returned in two parallel arrays.
|
|
*
|
|
* This extension is needed by the FreeType/2 OS/2 Font Driver.
|
|
*
|
|
******************************************************************/
|
|
|
|
|
|
#include "ftxwidth.h"
|
|
#include "ttdebug.h"
|
|
#include "ttobjs.h"
|
|
#include "ttfile.h"
|
|
#include "tttags.h"
|
|
#include "ttload.h"
|
|
|
|
/* Required by the tracing mode */
|
|
|
|
#undef TT_COMPONENT
|
|
#define TT_COMPONENT trace_any
|
|
|
|
|
|
/******************************************************************/
|
|
/* */
|
|
/* Function: TT_Get_Face_Widths */
|
|
/* */
|
|
/* Description: Returns the widths and/or heights of a given */
|
|
/* range of glyphs for a face. */
|
|
/* */
|
|
/* Input: */
|
|
/* face :: face handle */
|
|
/* */
|
|
/* first_glyph :: first glyph in range */
|
|
/* */
|
|
/* last_glyph :: last glyph in range */
|
|
/* */
|
|
/* widths :: address of table receiving the widths */
|
|
/* expressed in font units (ushorts). Set */
|
|
/* this parameter to NULL if you're not */
|
|
/* interested by these values. */
|
|
/* */
|
|
/* heights :: address of table receiving the heights */
|
|
/* expressed in font units (ushorts). Set */
|
|
/* this parameter to NULL if you're not */
|
|
/* interested by these values. */
|
|
/* */
|
|
/* Returns: */
|
|
/* Error code */
|
|
/* */
|
|
/* */
|
|
/******************************************************************/
|
|
|
|
EXPORT_FUNC
|
|
TT_Error TT_Get_Face_Widths( TT_Face face,
|
|
TT_UShort first_glyph,
|
|
TT_UShort last_glyph,
|
|
TT_UShort* widths,
|
|
TT_UShort* heights )
|
|
{
|
|
DEFINE_ALL_LOCALS;
|
|
|
|
PFace faze = HANDLE_Face(face);
|
|
UShort n;
|
|
Long table;
|
|
|
|
ULong glyf_offset; /* offset of glyph table in file */
|
|
UShort zero_width = 0; /* width of glyph 0 */
|
|
UShort zero_height = 0; /* height of glyph 0 */
|
|
|
|
Bool zero_loaded = 0;
|
|
|
|
#ifndef TT_HUGE_PTR
|
|
PStorage locations;
|
|
#else
|
|
Storage TT_HUGE_PTR * locations;
|
|
#endif
|
|
TT_BBox bbox;
|
|
|
|
|
|
if ( !faze )
|
|
return TT_Err_Invalid_Face_Handle;
|
|
|
|
if ( last_glyph >= faze->numGlyphs ||
|
|
first_glyph > last_glyph )
|
|
return TT_Err_Invalid_Argument;
|
|
|
|
/* find "glyf" table */
|
|
table = TT_LookUp_Table( faze, TTAG_glyf );
|
|
if ( table < 0 )
|
|
{
|
|
PERROR(( "ERROR: there is no glyph table in this font file!\n" ));
|
|
return TT_Err_Glyf_Table_Missing;
|
|
}
|
|
glyf_offset = faze->dirTables[table].Offset;
|
|
|
|
/* now access stream */
|
|
if ( USE_Stream( faze->stream, stream ) )
|
|
return error;
|
|
|
|
locations = faze->glyphLocations + first_glyph;
|
|
|
|
/* loop to load each glyph in the range */
|
|
for ( n = first_glyph; n <= last_glyph; n++ )
|
|
{
|
|
if ( n + 1 < faze->numGlyphs &&
|
|
locations[0] == locations[1] )
|
|
{
|
|
/* Note : Glyph 0 is always used to indicate a missing glyph */
|
|
/* in a range. We must thus return its width and height */
|
|
/* where appropriate when we find an undefined glyph. */
|
|
if ( zero_loaded == 0 )
|
|
{
|
|
if ( FILE_Seek( glyf_offset + faze->glyphLocations[0] ) ||
|
|
ACCESS_Frame( 10L ) )
|
|
goto Fail;
|
|
|
|
(void)GET_Short(); /* skip number of contours */
|
|
|
|
bbox.xMin = GET_Short();
|
|
bbox.yMin = GET_Short();
|
|
bbox.xMax = GET_Short();
|
|
bbox.yMax = GET_Short();
|
|
|
|
FORGET_Frame();
|
|
|
|
zero_width = (UShort)(bbox.xMax - bbox.xMin);
|
|
zero_height = (UShort)(bbox.yMax - bbox.yMin);
|
|
zero_loaded = 1;
|
|
}
|
|
|
|
if ( widths )
|
|
*widths++ = zero_width;
|
|
|
|
if ( heights )
|
|
*heights++ = zero_height;
|
|
}
|
|
else
|
|
{
|
|
/* normal glyph, read header */
|
|
if ( FILE_Seek( glyf_offset + locations[0] ) ||
|
|
ACCESS_Frame( 10L ) )
|
|
goto Fail;
|
|
|
|
(void)GET_Short(); /* skip number of contours */
|
|
|
|
bbox.xMin = GET_Short();
|
|
bbox.yMin = GET_Short();
|
|
bbox.xMax = GET_Short();
|
|
bbox.yMax = GET_Short();
|
|
|
|
FORGET_Frame();
|
|
|
|
if ( widths )
|
|
*widths++ = (UShort)(bbox.xMax - bbox.xMin);
|
|
|
|
if ( heights )
|
|
*heights++ = (UShort)(bbox.yMax - bbox.yMin);
|
|
}
|
|
}
|
|
|
|
Fail:
|
|
DONE_Stream( stream );
|
|
return error;
|
|
}
|
|
|
|
|
|
/* END */
|