2000-06-25 08:47:11 +02:00
|
|
|
/***************************************************************************/
|
|
|
|
/* */
|
|
|
|
/* t1hinter.c */
|
|
|
|
/* */
|
|
|
|
/* Type 1 hinter (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. */
|
|
|
|
/* */
|
|
|
|
/***************************************************************************/
|
|
|
|
|
|
|
|
|
|
|
|
/*************************************************************************/
|
|
|
|
/* */
|
|
|
|
/* The Hinter is in charge of fitting th scaled outline to the pixel */
|
|
|
|
/* grid in order to considerably improve the quality of the Type 1 font */
|
|
|
|
/* driver's output. */
|
|
|
|
/* */
|
|
|
|
/*************************************************************************/
|
|
|
|
|
1999-12-17 00:11:37 +01:00
|
|
|
|
2000-05-11 20:23:52 +02:00
|
|
|
#include <freetype/internal/ftdebug.h>
|
2000-07-08 21:51:42 +02:00
|
|
|
|
|
|
|
|
2000-07-08 02:41:13 +02:00
|
|
|
#ifdef FT_FLAT_COMPILE
|
2000-07-08 21:51:42 +02:00
|
|
|
|
2000-07-08 02:41:13 +02:00
|
|
|
#include "t1objs.h"
|
|
|
|
#include "t1hinter.h"
|
2000-07-08 21:51:42 +02:00
|
|
|
|
2000-07-08 02:41:13 +02:00
|
|
|
#else
|
2000-07-08 21:51:42 +02:00
|
|
|
|
2000-07-08 02:41:13 +02:00
|
|
|
#include <type1/t1objs.h>
|
|
|
|
#include <type1/t1hinter.h>
|
|
|
|
|
2000-07-08 21:51:42 +02:00
|
|
|
#endif
|
1999-12-17 00:11:37 +01:00
|
|
|
|
2000-06-25 08:47:11 +02:00
|
|
|
|
|
|
|
/*************************************************************************/
|
|
|
|
/* */
|
|
|
|
/* 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. */
|
|
|
|
/* */
|
1999-12-17 00:11:37 +01:00
|
|
|
#undef FT_COMPONENT
|
2000-06-25 08:47:11 +02:00
|
|
|
#define FT_COMPONENT trace_t1hint
|
1999-12-17 00:11:37 +01:00
|
|
|
|
|
|
|
|
|
|
|
#undef ONE_PIXEL
|
|
|
|
#define ONE_PIXEL 64
|
|
|
|
|
|
|
|
#undef ROUND
|
2000-06-25 08:47:11 +02:00
|
|
|
#define ROUND( x ) ( ( x + ONE_PIXEL / 2 ) & -ONE_PIXEL )
|
1999-12-17 00:11:37 +01:00
|
|
|
|
|
|
|
#undef SCALE
|
2000-06-25 08:47:11 +02:00
|
|
|
#define SCALE( val ) FT_MulFix( val, scale )
|
1999-12-17 00:11:37 +01:00
|
|
|
|
|
|
|
/* various constants used to describe the alignment of a horizontal */
|
|
|
|
/* stem with regards to the blue zones */
|
2000-06-25 08:47:11 +02:00
|
|
|
|
1999-12-17 00:11:37 +01:00
|
|
|
#define T1_ALIGN_NONE 0
|
|
|
|
#define T1_ALIGN_BOTTOM 1
|
|
|
|
#define T1_ALIGN_TOP 2
|
|
|
|
#define T1_ALIGN_BOTH 3
|
|
|
|
|
|
|
|
|
2000-06-25 08:47:11 +02:00
|
|
|
/* very simple bubble sort (not a lot of elements, mostly */
|
|
|
|
/* pre-sorted, no need for quicksort) */
|
2000-06-21 05:03:28 +02:00
|
|
|
|
2000-06-25 08:47:11 +02:00
|
|
|
static
|
|
|
|
void t1_sort_blues( FT_Int* blues,
|
|
|
|
FT_Int count )
|
|
|
|
{
|
|
|
|
FT_Int i, swap;
|
|
|
|
FT_Int* cur;
|
- MAJOR INTERNAL REDESIGN:
A lot of internal modifications have been performed lately on the
source in order to provide the following enhancements:
- more generic module support:
The FT_Module type is now defined to represent a handle to a given
module. The file <freetype/ftmodule.h> contains the FT_Module_Class
definition, as well as the module-loading public API
The FT_Driver type is still defined, and still represents a pointer
to a font driver. Note that FT_Add_Driver is replaced by FT_Add_Module,
FT_Get_Driver by FT_Get_Module, etc..
- support for generic glyph image types:
The FT_Renderer type is a pointer to a module used to perform various
operations on glyph image.
Each renderer is capable of handling images in a single format
(e.g. ft_glyph_format_outline). Its functions are used to:
- transform an glyph image
- render a glyph image into a bitmap
- return the control box (dimensions) of a given glyph image
The scan converters "ftraster.c" and "ftgrays.c" have been moved
to the new directory "src/renderer", and are used to provide two
default renderer modules.
One corresponds to the "standard" scan-converter, the other to the
"smooth" one.
The current renderer can be set through the new function
FT_Set_Renderer.
The old raster-related function FT_Set_Raster, FT_Get_Raster and
FT_Set_Raster_Mode have now disappeared, in favor of the new:
FT_Get_Renderer
FT_Set_Renderer
see the file <freetype/ftrender.h> for more details..
These changes were necessary to properly support different scalable
formats in the future, like bi-color glyphs, etc..
- glyph loader object:
A new internal object, called a 'glyph loader' has been introduced
in the base layer. It is used by all scalable format font drivers
to load glyphs and composites.
This object has been created to reduce the code size of each driver,
as each one of them basically re-implemented its functionality.
See <freetype/internal/ftobjs.h> and the FT_GlyphLoader type for
more information..
- FT_GlyphSlot had new fields:
In order to support extended features (see below), the FT_GlyphSlot
structure has a few new fields:
linearHoriAdvance: this field gives the linearly scaled (i.e.
scaled but unhinted) advance width for the glyph,
expressed as a 16.16 fixed pixel value. This
is useful to perform WYSIWYG text.
linearVertAdvance: this field gives the linearly scaled advance
height for the glyph (relevant in vertical glyph
layouts only). This is useful to perform
WYSIWYG text.
Note that the two above field replace the removed "metrics2" field
in the glyph slot.
advance: this field is a vector that gives the transformed
advance for the glyph. By default, it corresponds
to the advance width, unless FT_LOAD_VERTICAL_LAYOUT
was specified when calling FT_Load_Glyph or FT_Load_Char
bitmap_left: this field gives the distance in integer pixels from
the current pen position to the left-most pixel of
a glyph image WHEN IT IS A BITMAP. It is only valid
when the "format" field is set to
"ft_glyph_format_bitmap", for example, after calling
the new function FT_Render_Glyph.
bitmap_top: this field gives the distance in integer pixels from
the current pen position (located on the baseline) to
the top-most pixel of the glyph image WHEN IT IS A
BITMAP. Positive values correspond to upwards Y.
loader: this is a new private field for the glyph slot. Client
applications should not touch it..
- support for transforms and direct rendering in FT_Load_Glyph:
Most of the functionality found in <freetype/ftglyph.h> has been
moved to the core library. Hence, the following:
- a transform can be specified for a face through FT_Set_Transform.
this transform is applied by FT_Load_Glyph to scalable glyph images
(i.e. NOT TO BITMAPS) before the function returns, unless the
bit flag FT_LOAD_IGNORE_TRANSFORM was set in the load flags..
- once a glyph image has been loaded, it can be directly converted to
a bitmap by using the new FT_Render_Glyph function. Note that this
function takes the glyph image from the glyph slot, and converts
it to a bitmap whose properties are returned in "face.glyph.bitmap",
"face.glyph.bitmap_left" and "face.glyph.bitmap_top". The original
native image might be lost after the conversion.
- when using the new bit flag FT_LOAD_RENDER, the FT_Load_Glyph
and FT_Load_Char functions will call FT_Render_Glyph automatically
when needed.
2000-06-22 02:17:42 +02:00
|
|
|
|
1999-12-17 00:11:37 +01:00
|
|
|
|
2000-06-25 08:47:11 +02:00
|
|
|
for ( i = 2; i < count; i += 2 )
|
|
|
|
{
|
|
|
|
cur = blues + i;
|
|
|
|
do
|
|
|
|
{
|
|
|
|
if ( cur[-1] < cur[0] )
|
|
|
|
break;
|
|
|
|
|
|
|
|
swap = cur[-2]; cur[-2] = cur[0]; cur[0] = swap;
|
|
|
|
swap = cur[-1]; cur[-1] = cur[1]; cur[1] = swap;
|
|
|
|
cur -= 2;
|
2000-07-03 09:09:09 +02:00
|
|
|
|
2000-06-25 08:47:11 +02:00
|
|
|
} while ( cur > blues );
|
|
|
|
}
|
|
|
|
}
|
1999-12-17 00:11:37 +01:00
|
|
|
|
2000-06-25 08:47:11 +02:00
|
|
|
|
|
|
|
/*************************************************************************/
|
|
|
|
/* */
|
|
|
|
/* <Function> */
|
|
|
|
/* t1_set_blue_zones */
|
|
|
|
/* */
|
|
|
|
/* <Description> */
|
|
|
|
/* Sets a size object's blue zones during reset. This will compute */
|
|
|
|
/* the `snap' zone corresponding to each blue zone. */
|
|
|
|
/* */
|
|
|
|
/* <InOut> */
|
|
|
|
/* size :: A handle to target size object. */
|
|
|
|
/* */
|
|
|
|
/* <Return> */
|
|
|
|
/* FreeType error code. 0 means success. */
|
|
|
|
/* */
|
|
|
|
/* <Note> */
|
|
|
|
/* This functions does the following: */
|
|
|
|
/* */
|
|
|
|
/* 1. It extracts the bottom and top blue zones from the face object. */
|
|
|
|
/* */
|
|
|
|
/* 2. Each zone is then grown by `BlueFuzz', overlapping is */
|
|
|
|
/* eliminated by adjusting the zone edges appropriately. */
|
|
|
|
/* */
|
|
|
|
/* 3. For each zone, we keep its original font units position, its */
|
|
|
|
/* original scaled position, as well as its grown/adjusted edges. */
|
|
|
|
/* */
|
1999-12-17 00:11:37 +01:00
|
|
|
static
|
2000-06-16 21:34:52 +02:00
|
|
|
FT_Error t1_set_blue_zones( T1_Size size )
|
1999-12-17 00:11:37 +01:00
|
|
|
{
|
2000-06-25 08:47:11 +02:00
|
|
|
T1_Face face = (T1_Face)size->root.face;
|
|
|
|
T1_Private* priv = &face->type1.private_dict;
|
|
|
|
FT_Int n;
|
|
|
|
FT_Int blues[24];
|
|
|
|
FT_Int num_bottom;
|
|
|
|
FT_Int num_top;
|
|
|
|
FT_Int num_blues;
|
|
|
|
T1_Size_Hints* hints = size->hints;
|
|
|
|
T1_Snap_Zone* zone;
|
|
|
|
FT_Pos pix, orus;
|
|
|
|
FT_Pos min, max, threshold;
|
|
|
|
FT_Fixed scale;
|
|
|
|
FT_Bool is_bottom;
|
|
|
|
|
|
|
|
|
|
|
|
/***********************************************************************/
|
|
|
|
/* */
|
|
|
|
/* copy bottom and top blue zones in local arrays */
|
|
|
|
/* */
|
1999-12-17 00:11:37 +01:00
|
|
|
|
|
|
|
/* First of all, check the sizes of the /BlueValues and /OtherBlues */
|
2000-06-25 08:47:11 +02:00
|
|
|
/* tables. They all must contain an even number of arguments. */
|
1999-12-17 00:11:37 +01:00
|
|
|
if ( priv->num_other_blues & 1 ||
|
2000-06-01 05:27:48 +02:00
|
|
|
priv->num_blue_values & 1 )
|
1999-12-17 00:11:37 +01:00
|
|
|
{
|
2000-06-25 08:47:11 +02:00
|
|
|
FT_ERROR(( "t1_set_blue_zones: odd number of blue values\n" ));
|
1999-12-17 00:11:37 +01:00
|
|
|
return T1_Err_Syntax_Error;
|
|
|
|
}
|
|
|
|
|
2000-06-25 08:47:11 +02:00
|
|
|
/* copy the bottom blue zones from /OtherBlues */
|
1999-12-17 00:11:37 +01:00
|
|
|
num_top = 0;
|
|
|
|
num_bottom = priv->num_other_blues;
|
|
|
|
|
2000-06-25 08:47:11 +02:00
|
|
|
for ( n = 0; n < num_bottom; n++ )
|
1999-12-17 00:11:37 +01:00
|
|
|
blues[n] = priv->other_blues[n];
|
|
|
|
|
2000-06-25 08:47:11 +02:00
|
|
|
/* add the first blue zone in /BlueValues to the table */
|
2000-06-01 05:27:48 +02:00
|
|
|
num_top = priv->num_blue_values - 2;
|
1999-12-17 00:11:37 +01:00
|
|
|
if ( num_top >= 0 )
|
|
|
|
{
|
2000-06-25 08:47:11 +02:00
|
|
|
blues[num_bottom ] = priv->blue_values[0];
|
|
|
|
blues[num_bottom + 1] = priv->blue_values[1];
|
1999-12-17 00:11:37 +01:00
|
|
|
|
|
|
|
num_bottom += 2;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* sort the bottom blue zones */
|
|
|
|
t1_sort_blues( blues, num_bottom );
|
|
|
|
|
|
|
|
hints->num_bottom_zones = num_bottom >> 1;
|
|
|
|
|
|
|
|
/* now copy the /BlueValues to the top of the blues array */
|
|
|
|
if ( num_top > 0 )
|
|
|
|
{
|
|
|
|
for ( n = 0; n < num_top; n++ )
|
2000-06-25 08:47:11 +02:00
|
|
|
blues[num_bottom + n] = priv->blue_values[n + 2];
|
1999-12-17 00:11:37 +01:00
|
|
|
|
|
|
|
/* sort the top blue zones */
|
|
|
|
t1_sort_blues( blues + num_bottom, num_top );
|
|
|
|
}
|
|
|
|
else
|
|
|
|
num_top = 0;
|
|
|
|
|
|
|
|
num_blues = num_top + num_bottom;
|
|
|
|
hints->num_blue_zones = ( num_blues ) >> 1;
|
|
|
|
|
2000-06-25 08:47:11 +02:00
|
|
|
/***********************************************************************/
|
|
|
|
/* */
|
|
|
|
/* build blue snap zones from the local blues arrays */
|
|
|
|
/* */
|
1999-12-17 00:11:37 +01:00
|
|
|
|
|
|
|
scale = size->root.metrics.y_scale;
|
|
|
|
zone = hints->blue_zones;
|
2000-06-25 08:47:11 +02:00
|
|
|
threshold = ONE_PIXEL / 4; /* 0.25 pixels */
|
1999-12-17 00:11:37 +01:00
|
|
|
|
2000-06-25 08:47:11 +02:00
|
|
|
for ( n = 0; n < num_blues; n += 2, zone++ )
|
1999-12-17 00:11:37 +01:00
|
|
|
{
|
2000-06-25 08:47:11 +02:00
|
|
|
is_bottom = n < num_bottom ? 1 : 0;
|
1999-12-17 00:11:37 +01:00
|
|
|
|
2000-06-25 08:47:11 +02:00
|
|
|
orus = blues[n + is_bottom]; /* get alignement coordinate */
|
|
|
|
pix = SCALE( orus ); /* scale it */
|
1999-12-17 00:11:37 +01:00
|
|
|
|
2000-06-25 08:47:11 +02:00
|
|
|
min = SCALE( blues[n ] - priv->blue_fuzz );
|
|
|
|
max = SCALE( blues[n + 1] + priv->blue_fuzz );
|
1999-12-17 00:11:37 +01:00
|
|
|
|
2000-06-25 08:47:11 +02:00
|
|
|
if ( min > pix - threshold )
|
|
|
|
min = pix - threshold;
|
|
|
|
if ( max < pix + threshold )
|
|
|
|
max = pix + threshold;
|
1999-12-17 00:11:37 +01:00
|
|
|
|
|
|
|
zone->orus = orus;
|
|
|
|
zone->pix = pix;
|
|
|
|
zone->min = min;
|
|
|
|
zone->max = max;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* adjust edges in case of overlap */
|
|
|
|
zone = hints->blue_zones;
|
2000-06-25 08:47:11 +02:00
|
|
|
for ( n = 0; n < num_blues - 2; n += 2, zone++ )
|
1999-12-17 00:11:37 +01:00
|
|
|
{
|
2000-06-25 08:47:11 +02:00
|
|
|
if ( n != num_bottom - 2 &&
|
1999-12-17 00:11:37 +01:00
|
|
|
zone[0].max > zone[1].min )
|
2000-06-25 08:47:11 +02:00
|
|
|
zone[0].max = zone[1].min = ( zone[0].pix + zone[1].pix ) / 2;
|
1999-12-17 00:11:37 +01:00
|
|
|
}
|
|
|
|
|
2000-06-25 08:47:11 +02:00
|
|
|
/* compare the current pixel size with the BlueScale value */
|
|
|
|
/* to know whether to supress overshoots */
|
2000-05-17 01:44:38 +02:00
|
|
|
|
|
|
|
hints->supress_overshoots =
|
2000-06-25 08:47:11 +02:00
|
|
|
size->root.metrics.y_ppem < FT_MulFix( 1000, priv->blue_scale );
|
2000-05-17 01:44:38 +02:00
|
|
|
|
- MAJOR INTERNAL REDESIGN:
A lot of internal modifications have been performed lately on the
source in order to provide the following enhancements:
- more generic module support:
The FT_Module type is now defined to represent a handle to a given
module. The file <freetype/ftmodule.h> contains the FT_Module_Class
definition, as well as the module-loading public API
The FT_Driver type is still defined, and still represents a pointer
to a font driver. Note that FT_Add_Driver is replaced by FT_Add_Module,
FT_Get_Driver by FT_Get_Module, etc..
- support for generic glyph image types:
The FT_Renderer type is a pointer to a module used to perform various
operations on glyph image.
Each renderer is capable of handling images in a single format
(e.g. ft_glyph_format_outline). Its functions are used to:
- transform an glyph image
- render a glyph image into a bitmap
- return the control box (dimensions) of a given glyph image
The scan converters "ftraster.c" and "ftgrays.c" have been moved
to the new directory "src/renderer", and are used to provide two
default renderer modules.
One corresponds to the "standard" scan-converter, the other to the
"smooth" one.
The current renderer can be set through the new function
FT_Set_Renderer.
The old raster-related function FT_Set_Raster, FT_Get_Raster and
FT_Set_Raster_Mode have now disappeared, in favor of the new:
FT_Get_Renderer
FT_Set_Renderer
see the file <freetype/ftrender.h> for more details..
These changes were necessary to properly support different scalable
formats in the future, like bi-color glyphs, etc..
- glyph loader object:
A new internal object, called a 'glyph loader' has been introduced
in the base layer. It is used by all scalable format font drivers
to load glyphs and composites.
This object has been created to reduce the code size of each driver,
as each one of them basically re-implemented its functionality.
See <freetype/internal/ftobjs.h> and the FT_GlyphLoader type for
more information..
- FT_GlyphSlot had new fields:
In order to support extended features (see below), the FT_GlyphSlot
structure has a few new fields:
linearHoriAdvance: this field gives the linearly scaled (i.e.
scaled but unhinted) advance width for the glyph,
expressed as a 16.16 fixed pixel value. This
is useful to perform WYSIWYG text.
linearVertAdvance: this field gives the linearly scaled advance
height for the glyph (relevant in vertical glyph
layouts only). This is useful to perform
WYSIWYG text.
Note that the two above field replace the removed "metrics2" field
in the glyph slot.
advance: this field is a vector that gives the transformed
advance for the glyph. By default, it corresponds
to the advance width, unless FT_LOAD_VERTICAL_LAYOUT
was specified when calling FT_Load_Glyph or FT_Load_Char
bitmap_left: this field gives the distance in integer pixels from
the current pen position to the left-most pixel of
a glyph image WHEN IT IS A BITMAP. It is only valid
when the "format" field is set to
"ft_glyph_format_bitmap", for example, after calling
the new function FT_Render_Glyph.
bitmap_top: this field gives the distance in integer pixels from
the current pen position (located on the baseline) to
the top-most pixel of the glyph image WHEN IT IS A
BITMAP. Positive values correspond to upwards Y.
loader: this is a new private field for the glyph slot. Client
applications should not touch it..
- support for transforms and direct rendering in FT_Load_Glyph:
Most of the functionality found in <freetype/ftglyph.h> has been
moved to the core library. Hence, the following:
- a transform can be specified for a face through FT_Set_Transform.
this transform is applied by FT_Load_Glyph to scalable glyph images
(i.e. NOT TO BITMAPS) before the function returns, unless the
bit flag FT_LOAD_IGNORE_TRANSFORM was set in the load flags..
- once a glyph image has been loaded, it can be directly converted to
a bitmap by using the new FT_Render_Glyph function. Note that this
function takes the glyph image from the glyph slot, and converts
it to a bitmap whose properties are returned in "face.glyph.bitmap",
"face.glyph.bitmap_left" and "face.glyph.bitmap_top". The original
native image might be lost after the conversion.
- when using the new bit flag FT_LOAD_RENDER, the FT_Load_Glyph
and FT_Load_Char functions will call FT_Render_Glyph automatically
when needed.
2000-06-22 02:17:42 +02:00
|
|
|
#ifdef FT_DEBUG_LEVEL_TRACE
|
2000-06-21 05:03:28 +02:00
|
|
|
|
2000-06-25 08:47:11 +02:00
|
|
|
/* now print the new blue values in tracing mode */
|
|
|
|
|
|
|
|
FT_TRACE2(( "Blue Zones for size object at $%08lx:\n", (long)size ));
|
1999-12-17 00:11:37 +01:00
|
|
|
FT_TRACE2(( " orus pix min max\n" ));
|
|
|
|
FT_TRACE2(( "-------------------------------\n" ));
|
2000-05-17 01:44:38 +02:00
|
|
|
|
1999-12-17 00:11:37 +01:00
|
|
|
zone = hints->blue_zones;
|
|
|
|
for ( n = 0; n < hints->num_blue_zones; n++ )
|
|
|
|
{
|
|
|
|
FT_TRACE2(( " %3d %.2f %.2f %.2f\n",
|
2000-06-25 08:47:11 +02:00
|
|
|
zone->orus,
|
|
|
|
zone->pix / 64.0,
|
|
|
|
zone->min / 64.0,
|
|
|
|
zone->max / 64.0 ));
|
1999-12-17 00:11:37 +01:00
|
|
|
zone++;
|
|
|
|
}
|
2000-06-25 08:47:11 +02:00
|
|
|
FT_TRACE2(( "\nOvershoots are %s\n\n",
|
|
|
|
hints->supress_overshoots ? "supressed" : "active" ));
|
1999-12-17 00:11:37 +01:00
|
|
|
|
|
|
|
#endif /* DEBUG_LEVEL_TRACE */
|
2000-05-17 01:44:38 +02:00
|
|
|
|
1999-12-17 00:11:37 +01:00
|
|
|
return T1_Err_Ok;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2000-06-25 08:47:11 +02:00
|
|
|
/*************************************************************************/
|
|
|
|
/* */
|
|
|
|
/* <Function> */
|
|
|
|
/* t1_set_snap_zones */
|
|
|
|
/* */
|
|
|
|
/* <Description> */
|
|
|
|
/* This function set a size object's stem snap zones. */
|
|
|
|
/* */
|
|
|
|
/* <InOut> */
|
|
|
|
/* size :: A handle to the target size object. */
|
|
|
|
/* */
|
|
|
|
/* <Return> */
|
|
|
|
/* FreeType error code. 0 means success. */
|
|
|
|
/* */
|
|
|
|
/* <Note> */
|
|
|
|
/* This function performs the following: */
|
|
|
|
/* */
|
|
|
|
/* 1. It reads and scales the stem snap widths from the parent face. */
|
|
|
|
/* */
|
|
|
|
/* 2. A `snap zone' is computed for each snap width, by `growing' it */
|
|
|
|
/* with a threshold of 1/2 pixel. Overlapping is avoided through */
|
|
|
|
/* proper edge adjustment. */
|
|
|
|
/* */
|
|
|
|
/* 3. Each width whose zone contain the scaled standard set width is */
|
|
|
|
/* removed from the table. */
|
|
|
|
/* */
|
|
|
|
/* 4. Finally, the standard set width is scaled, and its correponding */
|
|
|
|
/* `snap zone' is inserted into the sorted snap zones table. */
|
|
|
|
/* */
|
1999-12-17 00:11:37 +01:00
|
|
|
static
|
2000-06-16 21:34:52 +02:00
|
|
|
FT_Error t1_set_snap_zones( T1_Size size )
|
1999-12-17 00:11:37 +01:00
|
|
|
{
|
2000-06-25 08:47:11 +02:00
|
|
|
FT_Int n, direction, n_zones, num_zones;
|
|
|
|
T1_Snap_Zone* zone;
|
|
|
|
T1_Snap_Zone* base_zone;
|
|
|
|
FT_Short* orgs;
|
|
|
|
FT_Pos standard_width;
|
|
|
|
FT_Fixed scale;
|
|
|
|
|
|
|
|
T1_Face face = (T1_Face)size->root.face;
|
|
|
|
T1_Private* priv = &face->type1.private_dict;
|
1999-12-17 00:11:37 +01:00
|
|
|
T1_Size_Hints* hints = size->hints;
|
|
|
|
|
2000-06-25 08:47:11 +02:00
|
|
|
|
1999-12-17 00:11:37 +01:00
|
|
|
/* start with horizontal snap zones */
|
|
|
|
direction = 0;
|
2000-05-24 23:12:02 +02:00
|
|
|
standard_width = priv->standard_width[0];
|
1999-12-17 00:11:37 +01:00
|
|
|
n_zones = priv->num_snap_widths;
|
|
|
|
base_zone = hints->snap_widths;
|
2000-06-01 05:27:48 +02:00
|
|
|
orgs = priv->snap_widths;
|
1999-12-17 00:11:37 +01:00
|
|
|
scale = size->root.metrics.x_scale;
|
2000-05-17 01:44:38 +02:00
|
|
|
|
2000-06-25 08:47:11 +02:00
|
|
|
while ( direction < 2 )
|
1999-12-17 00:11:37 +01:00
|
|
|
{
|
2000-06-25 08:47:11 +02:00
|
|
|
/*********************************************************************/
|
|
|
|
/* */
|
|
|
|
/* Read and scale stem snap widths table from the physical font */
|
|
|
|
/* record. */
|
|
|
|
/* */
|
|
|
|
|
2000-06-16 21:34:52 +02:00
|
|
|
FT_Pos prev, orus, pix, min, max, threshold;
|
2000-05-17 01:44:38 +02:00
|
|
|
|
2000-06-25 08:47:11 +02:00
|
|
|
|
|
|
|
threshold = ONE_PIXEL / 4;
|
1999-12-17 00:11:37 +01:00
|
|
|
zone = base_zone;
|
|
|
|
|
|
|
|
if ( n_zones > 0 )
|
|
|
|
{
|
|
|
|
orus = *orgs++;
|
|
|
|
pix = SCALE( orus );
|
2000-06-25 08:47:11 +02:00
|
|
|
min = pix - threshold;
|
|
|
|
max = pix + threshold;
|
1999-12-17 00:11:37 +01:00
|
|
|
|
|
|
|
zone->orus = orus;
|
|
|
|
zone->pix = pix;
|
|
|
|
zone->min = min;
|
|
|
|
prev = pix;
|
|
|
|
|
|
|
|
for ( n = 1; n < n_zones; n++ )
|
|
|
|
{
|
|
|
|
orus = *orgs++;
|
|
|
|
pix = SCALE( orus );
|
|
|
|
|
2000-06-25 08:47:11 +02:00
|
|
|
if ( pix - prev < 2 * threshold )
|
1999-12-17 00:11:37 +01:00
|
|
|
{
|
2000-06-25 08:47:11 +02:00
|
|
|
min = max = ( pix + prev ) / 2;
|
1999-12-17 00:11:37 +01:00
|
|
|
}
|
|
|
|
else
|
2000-06-25 08:47:11 +02:00
|
|
|
min = pix - threshold;
|
1999-12-17 00:11:37 +01:00
|
|
|
|
|
|
|
zone->max = max;
|
|
|
|
zone++;
|
|
|
|
zone->orus = orus;
|
|
|
|
zone->pix = pix;
|
|
|
|
zone->min = min;
|
|
|
|
|
2000-06-25 08:47:11 +02:00
|
|
|
max = pix + threshold;
|
1999-12-17 00:11:37 +01:00
|
|
|
prev = pix;
|
|
|
|
}
|
|
|
|
zone->max = max;
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef FT_DEBUG_LEVEL_TRACE
|
2000-05-17 01:44:38 +02:00
|
|
|
|
2000-06-25 08:47:11 +02:00
|
|
|
/* print the scaled stem snap values in tracing mode */
|
|
|
|
|
|
|
|
FT_TRACE2(( "Set_Snap_Zones: first %s pass\n",
|
|
|
|
direction ? "vertical" : "horizontal" ));
|
2000-05-17 01:44:38 +02:00
|
|
|
|
2000-06-25 08:47:11 +02:00
|
|
|
FT_TRACE2(( "Scaled original stem snap zones:\n" ));
|
1999-12-17 00:11:37 +01:00
|
|
|
FT_TRACE2(( " orus pix min max\n" ));
|
|
|
|
FT_TRACE2(( "-----------------------------\n" ));
|
2000-05-17 01:44:38 +02:00
|
|
|
|
1999-12-17 00:11:37 +01:00
|
|
|
zone = base_zone;
|
|
|
|
for ( n = 0; n < n_zones; n++, zone++ )
|
|
|
|
FT_TRACE2(( " %3d %.2f %.2f %.2f\n",
|
2000-06-25 08:47:11 +02:00
|
|
|
zone->orus,
|
|
|
|
zone->pix / 64.0,
|
|
|
|
zone->min / 64.0,
|
|
|
|
zone->max / 64.0 ));
|
- MAJOR INTERNAL REDESIGN:
A lot of internal modifications have been performed lately on the
source in order to provide the following enhancements:
- more generic module support:
The FT_Module type is now defined to represent a handle to a given
module. The file <freetype/ftmodule.h> contains the FT_Module_Class
definition, as well as the module-loading public API
The FT_Driver type is still defined, and still represents a pointer
to a font driver. Note that FT_Add_Driver is replaced by FT_Add_Module,
FT_Get_Driver by FT_Get_Module, etc..
- support for generic glyph image types:
The FT_Renderer type is a pointer to a module used to perform various
operations on glyph image.
Each renderer is capable of handling images in a single format
(e.g. ft_glyph_format_outline). Its functions are used to:
- transform an glyph image
- render a glyph image into a bitmap
- return the control box (dimensions) of a given glyph image
The scan converters "ftraster.c" and "ftgrays.c" have been moved
to the new directory "src/renderer", and are used to provide two
default renderer modules.
One corresponds to the "standard" scan-converter, the other to the
"smooth" one.
The current renderer can be set through the new function
FT_Set_Renderer.
The old raster-related function FT_Set_Raster, FT_Get_Raster and
FT_Set_Raster_Mode have now disappeared, in favor of the new:
FT_Get_Renderer
FT_Set_Renderer
see the file <freetype/ftrender.h> for more details..
These changes were necessary to properly support different scalable
formats in the future, like bi-color glyphs, etc..
- glyph loader object:
A new internal object, called a 'glyph loader' has been introduced
in the base layer. It is used by all scalable format font drivers
to load glyphs and composites.
This object has been created to reduce the code size of each driver,
as each one of them basically re-implemented its functionality.
See <freetype/internal/ftobjs.h> and the FT_GlyphLoader type for
more information..
- FT_GlyphSlot had new fields:
In order to support extended features (see below), the FT_GlyphSlot
structure has a few new fields:
linearHoriAdvance: this field gives the linearly scaled (i.e.
scaled but unhinted) advance width for the glyph,
expressed as a 16.16 fixed pixel value. This
is useful to perform WYSIWYG text.
linearVertAdvance: this field gives the linearly scaled advance
height for the glyph (relevant in vertical glyph
layouts only). This is useful to perform
WYSIWYG text.
Note that the two above field replace the removed "metrics2" field
in the glyph slot.
advance: this field is a vector that gives the transformed
advance for the glyph. By default, it corresponds
to the advance width, unless FT_LOAD_VERTICAL_LAYOUT
was specified when calling FT_Load_Glyph or FT_Load_Char
bitmap_left: this field gives the distance in integer pixels from
the current pen position to the left-most pixel of
a glyph image WHEN IT IS A BITMAP. It is only valid
when the "format" field is set to
"ft_glyph_format_bitmap", for example, after calling
the new function FT_Render_Glyph.
bitmap_top: this field gives the distance in integer pixels from
the current pen position (located on the baseline) to
the top-most pixel of the glyph image WHEN IT IS A
BITMAP. Positive values correspond to upwards Y.
loader: this is a new private field for the glyph slot. Client
applications should not touch it..
- support for transforms and direct rendering in FT_Load_Glyph:
Most of the functionality found in <freetype/ftglyph.h> has been
moved to the core library. Hence, the following:
- a transform can be specified for a face through FT_Set_Transform.
this transform is applied by FT_Load_Glyph to scalable glyph images
(i.e. NOT TO BITMAPS) before the function returns, unless the
bit flag FT_LOAD_IGNORE_TRANSFORM was set in the load flags..
- once a glyph image has been loaded, it can be directly converted to
a bitmap by using the new FT_Render_Glyph function. Note that this
function takes the glyph image from the glyph slot, and converts
it to a bitmap whose properties are returned in "face.glyph.bitmap",
"face.glyph.bitmap_left" and "face.glyph.bitmap_top". The original
native image might be lost after the conversion.
- when using the new bit flag FT_LOAD_RENDER, the FT_Load_Glyph
and FT_Load_Char functions will call FT_Render_Glyph automatically
when needed.
2000-06-22 02:17:42 +02:00
|
|
|
FT_TRACE2(( "\n" ));
|
2000-06-21 05:03:28 +02:00
|
|
|
|
- MAJOR INTERNAL REDESIGN:
A lot of internal modifications have been performed lately on the
source in order to provide the following enhancements:
- more generic module support:
The FT_Module type is now defined to represent a handle to a given
module. The file <freetype/ftmodule.h> contains the FT_Module_Class
definition, as well as the module-loading public API
The FT_Driver type is still defined, and still represents a pointer
to a font driver. Note that FT_Add_Driver is replaced by FT_Add_Module,
FT_Get_Driver by FT_Get_Module, etc..
- support for generic glyph image types:
The FT_Renderer type is a pointer to a module used to perform various
operations on glyph image.
Each renderer is capable of handling images in a single format
(e.g. ft_glyph_format_outline). Its functions are used to:
- transform an glyph image
- render a glyph image into a bitmap
- return the control box (dimensions) of a given glyph image
The scan converters "ftraster.c" and "ftgrays.c" have been moved
to the new directory "src/renderer", and are used to provide two
default renderer modules.
One corresponds to the "standard" scan-converter, the other to the
"smooth" one.
The current renderer can be set through the new function
FT_Set_Renderer.
The old raster-related function FT_Set_Raster, FT_Get_Raster and
FT_Set_Raster_Mode have now disappeared, in favor of the new:
FT_Get_Renderer
FT_Set_Renderer
see the file <freetype/ftrender.h> for more details..
These changes were necessary to properly support different scalable
formats in the future, like bi-color glyphs, etc..
- glyph loader object:
A new internal object, called a 'glyph loader' has been introduced
in the base layer. It is used by all scalable format font drivers
to load glyphs and composites.
This object has been created to reduce the code size of each driver,
as each one of them basically re-implemented its functionality.
See <freetype/internal/ftobjs.h> and the FT_GlyphLoader type for
more information..
- FT_GlyphSlot had new fields:
In order to support extended features (see below), the FT_GlyphSlot
structure has a few new fields:
linearHoriAdvance: this field gives the linearly scaled (i.e.
scaled but unhinted) advance width for the glyph,
expressed as a 16.16 fixed pixel value. This
is useful to perform WYSIWYG text.
linearVertAdvance: this field gives the linearly scaled advance
height for the glyph (relevant in vertical glyph
layouts only). This is useful to perform
WYSIWYG text.
Note that the two above field replace the removed "metrics2" field
in the glyph slot.
advance: this field is a vector that gives the transformed
advance for the glyph. By default, it corresponds
to the advance width, unless FT_LOAD_VERTICAL_LAYOUT
was specified when calling FT_Load_Glyph or FT_Load_Char
bitmap_left: this field gives the distance in integer pixels from
the current pen position to the left-most pixel of
a glyph image WHEN IT IS A BITMAP. It is only valid
when the "format" field is set to
"ft_glyph_format_bitmap", for example, after calling
the new function FT_Render_Glyph.
bitmap_top: this field gives the distance in integer pixels from
the current pen position (located on the baseline) to
the top-most pixel of the glyph image WHEN IT IS A
BITMAP. Positive values correspond to upwards Y.
loader: this is a new private field for the glyph slot. Client
applications should not touch it..
- support for transforms and direct rendering in FT_Load_Glyph:
Most of the functionality found in <freetype/ftglyph.h> has been
moved to the core library. Hence, the following:
- a transform can be specified for a face through FT_Set_Transform.
this transform is applied by FT_Load_Glyph to scalable glyph images
(i.e. NOT TO BITMAPS) before the function returns, unless the
bit flag FT_LOAD_IGNORE_TRANSFORM was set in the load flags..
- once a glyph image has been loaded, it can be directly converted to
a bitmap by using the new FT_Render_Glyph function. Note that this
function takes the glyph image from the glyph slot, and converts
it to a bitmap whose properties are returned in "face.glyph.bitmap",
"face.glyph.bitmap_left" and "face.glyph.bitmap_top". The original
native image might be lost after the conversion.
- when using the new bit flag FT_LOAD_RENDER, the FT_Load_Glyph
and FT_Load_Char functions will call FT_Render_Glyph automatically
when needed.
2000-06-22 02:17:42 +02:00
|
|
|
FT_TRACE2(( "Standard width = %d\n", standard_width ));
|
1999-12-17 00:11:37 +01:00
|
|
|
|
2000-06-25 08:47:11 +02:00
|
|
|
#endif /* FT_DEBUG_LEVEL_TRACE */
|
|
|
|
|
|
|
|
/*********************************************************************/
|
|
|
|
/* */
|
|
|
|
/* Now, each snap width which is in the range of the standard set */
|
|
|
|
/* width will be removed from the list. */
|
|
|
|
/* */
|
1999-12-17 00:11:37 +01:00
|
|
|
|
|
|
|
if ( standard_width > 0 )
|
|
|
|
{
|
|
|
|
T1_Snap_Zone* parent;
|
2000-06-16 21:34:52 +02:00
|
|
|
FT_Pos std_pix, std_min, std_max;
|
1999-12-17 00:11:37 +01:00
|
|
|
|
2000-06-25 08:47:11 +02:00
|
|
|
|
2000-05-17 01:44:38 +02:00
|
|
|
std_pix = SCALE( standard_width );
|
1999-12-17 00:11:37 +01:00
|
|
|
|
2000-06-25 08:47:11 +02:00
|
|
|
std_min = std_pix - threshold;
|
|
|
|
std_max = std_pix + threshold;
|
1999-12-17 00:11:37 +01:00
|
|
|
|
|
|
|
num_zones = 0;
|
|
|
|
zone = base_zone;
|
|
|
|
parent = base_zone;
|
|
|
|
|
|
|
|
for ( n = 0; n < n_zones; n++ )
|
|
|
|
{
|
|
|
|
if ( zone->pix >= std_min && zone->pix <= std_max )
|
|
|
|
{
|
|
|
|
/* this zone must be removed from the list */
|
2000-06-25 08:47:11 +02:00
|
|
|
if ( std_min > zone->min )
|
|
|
|
std_min = zone->min;
|
|
|
|
if ( std_max < zone->max )
|
|
|
|
std_max = zone->max;
|
1999-12-17 00:11:37 +01:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
*parent++ = *zone;
|
|
|
|
num_zones++;
|
|
|
|
}
|
|
|
|
zone++;
|
|
|
|
}
|
2000-05-17 01:44:38 +02:00
|
|
|
|
2000-06-25 08:47:11 +02:00
|
|
|
/*******************************************************************/
|
|
|
|
/* */
|
|
|
|
/* Now, insert the standard width zone */
|
|
|
|
/* */
|
2000-05-17 01:44:38 +02:00
|
|
|
|
2000-06-25 08:47:11 +02:00
|
|
|
zone = base_zone + num_zones;
|
1999-12-17 00:11:37 +01:00
|
|
|
while ( zone > base_zone && zone[-1].pix > std_max )
|
|
|
|
{
|
|
|
|
zone[0] = zone[-1];
|
2000-06-25 08:47:11 +02:00
|
|
|
zone--;
|
1999-12-17 00:11:37 +01:00
|
|
|
}
|
2000-05-17 01:44:38 +02:00
|
|
|
|
1999-12-17 00:11:37 +01:00
|
|
|
/* check border zones */
|
|
|
|
if ( zone > base_zone && zone[-1].max > std_min )
|
|
|
|
zone[-1].max = std_min;
|
2000-05-17 01:44:38 +02:00
|
|
|
|
2000-06-25 08:47:11 +02:00
|
|
|
if ( zone < base_zone + num_zones && zone[1].min < std_max )
|
1999-12-17 00:11:37 +01:00
|
|
|
zone[1].min = std_max;
|
2000-05-17 01:44:38 +02:00
|
|
|
|
1999-12-17 00:11:37 +01:00
|
|
|
zone->orus = standard_width;
|
|
|
|
zone->pix = std_pix;
|
|
|
|
zone->min = std_min;
|
|
|
|
zone->max = std_max;
|
2000-05-17 01:44:38 +02:00
|
|
|
|
1999-12-17 00:11:37 +01:00
|
|
|
num_zones++;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
num_zones = n_zones;
|
|
|
|
|
|
|
|
/* save total number of stem snaps now */
|
2000-06-25 08:47:11 +02:00
|
|
|
if ( direction )
|
|
|
|
hints->num_snap_heights = num_zones;
|
|
|
|
else
|
|
|
|
hints->num_snap_widths = num_zones;
|
1999-12-17 00:11:37 +01:00
|
|
|
|
|
|
|
#ifdef FT_DEBUG_LEVEL_TRACE
|
2000-05-17 01:44:38 +02:00
|
|
|
|
2000-06-25 08:47:11 +02:00
|
|
|
/* print the scaled stem snap values in tracing mode */
|
|
|
|
|
|
|
|
FT_TRACE2(( "Set_Snap_Zones: second %s pass\n",
|
|
|
|
direction ? "vertical" : "horizontal" ));
|
2000-05-17 01:44:38 +02:00
|
|
|
|
2000-06-25 08:47:11 +02:00
|
|
|
FT_TRACE2(( "Scaled clipped stem snap zones:\n" ));
|
1999-12-17 00:11:37 +01:00
|
|
|
FT_TRACE2(( " orus pix min max\n" ));
|
|
|
|
FT_TRACE2(( "-----------------------------\n" ));
|
2000-05-17 01:44:38 +02:00
|
|
|
|
1999-12-17 00:11:37 +01:00
|
|
|
zone = base_zone;
|
|
|
|
for ( n = 0; n < num_zones; n++, zone++ )
|
|
|
|
FT_TRACE2(( " %3d %.2f %.2f %.2f\n",
|
2000-06-25 08:47:11 +02:00
|
|
|
zone->orus,
|
|
|
|
zone->pix / 64.0,
|
|
|
|
zone->min / 64.0,
|
|
|
|
zone->max / 64.0 ));
|
1999-12-17 00:11:37 +01:00
|
|
|
FT_TRACE2(( "\n" ));
|
2000-05-17 01:44:38 +02:00
|
|
|
|
1999-12-17 00:11:37 +01:00
|
|
|
FT_TRACE2(( "Standard width = %d\n", standard_width ));
|
2000-06-25 08:47:11 +02:00
|
|
|
|
|
|
|
#endif /* FT_DEBUG_LEVEL_TRACE */
|
2000-05-17 01:44:38 +02:00
|
|
|
|
1999-12-17 00:11:37 +01:00
|
|
|
/* continue with vertical snap zone */
|
|
|
|
direction++;
|
2000-05-24 23:12:02 +02:00
|
|
|
standard_width = priv->standard_height[0];
|
1999-12-17 00:11:37 +01:00
|
|
|
n_zones = priv->num_snap_heights;
|
|
|
|
base_zone = hints->snap_heights;
|
2000-06-01 05:27:48 +02:00
|
|
|
orgs = priv->snap_heights;
|
1999-12-17 00:11:37 +01:00
|
|
|
scale = size->root.metrics.y_scale;
|
|
|
|
}
|
|
|
|
|
|
|
|
return T1_Err_Ok;
|
|
|
|
}
|
2000-05-17 01:44:38 +02:00
|
|
|
|
1999-12-17 00:11:37 +01:00
|
|
|
|
2000-06-25 08:47:11 +02:00
|
|
|
/*************************************************************************/
|
|
|
|
/* */
|
|
|
|
/* <Function> */
|
|
|
|
/* T1_New_Size_Hinter */
|
|
|
|
/* */
|
|
|
|
/* <Description> */
|
|
|
|
/* Allocates a new hinter structure for a given size object. */
|
|
|
|
/* */
|
|
|
|
/* <InOut> */
|
|
|
|
/* size :: A handle to the target size object. */
|
|
|
|
/* */
|
|
|
|
/* <Return> */
|
|
|
|
/* FreeType Error code. 0 means success. */
|
|
|
|
/* */
|
1999-12-17 00:11:37 +01:00
|
|
|
LOCAL_FUNC
|
2000-06-16 21:34:52 +02:00
|
|
|
FT_Error T1_New_Size_Hinter( T1_Size size )
|
1999-12-17 00:11:37 +01:00
|
|
|
{
|
|
|
|
FT_Memory memory = size->root.face->memory;
|
2000-05-17 01:44:38 +02:00
|
|
|
|
1999-12-17 00:11:37 +01:00
|
|
|
|
2000-06-25 08:47:11 +02:00
|
|
|
return MEM_Alloc( size->hints, sizeof ( *size->hints ) );
|
|
|
|
}
|
1999-12-17 00:11:37 +01:00
|
|
|
|
- MAJOR INTERNAL REDESIGN:
A lot of internal modifications have been performed lately on the
source in order to provide the following enhancements:
- more generic module support:
The FT_Module type is now defined to represent a handle to a given
module. The file <freetype/ftmodule.h> contains the FT_Module_Class
definition, as well as the module-loading public API
The FT_Driver type is still defined, and still represents a pointer
to a font driver. Note that FT_Add_Driver is replaced by FT_Add_Module,
FT_Get_Driver by FT_Get_Module, etc..
- support for generic glyph image types:
The FT_Renderer type is a pointer to a module used to perform various
operations on glyph image.
Each renderer is capable of handling images in a single format
(e.g. ft_glyph_format_outline). Its functions are used to:
- transform an glyph image
- render a glyph image into a bitmap
- return the control box (dimensions) of a given glyph image
The scan converters "ftraster.c" and "ftgrays.c" have been moved
to the new directory "src/renderer", and are used to provide two
default renderer modules.
One corresponds to the "standard" scan-converter, the other to the
"smooth" one.
The current renderer can be set through the new function
FT_Set_Renderer.
The old raster-related function FT_Set_Raster, FT_Get_Raster and
FT_Set_Raster_Mode have now disappeared, in favor of the new:
FT_Get_Renderer
FT_Set_Renderer
see the file <freetype/ftrender.h> for more details..
These changes were necessary to properly support different scalable
formats in the future, like bi-color glyphs, etc..
- glyph loader object:
A new internal object, called a 'glyph loader' has been introduced
in the base layer. It is used by all scalable format font drivers
to load glyphs and composites.
This object has been created to reduce the code size of each driver,
as each one of them basically re-implemented its functionality.
See <freetype/internal/ftobjs.h> and the FT_GlyphLoader type for
more information..
- FT_GlyphSlot had new fields:
In order to support extended features (see below), the FT_GlyphSlot
structure has a few new fields:
linearHoriAdvance: this field gives the linearly scaled (i.e.
scaled but unhinted) advance width for the glyph,
expressed as a 16.16 fixed pixel value. This
is useful to perform WYSIWYG text.
linearVertAdvance: this field gives the linearly scaled advance
height for the glyph (relevant in vertical glyph
layouts only). This is useful to perform
WYSIWYG text.
Note that the two above field replace the removed "metrics2" field
in the glyph slot.
advance: this field is a vector that gives the transformed
advance for the glyph. By default, it corresponds
to the advance width, unless FT_LOAD_VERTICAL_LAYOUT
was specified when calling FT_Load_Glyph or FT_Load_Char
bitmap_left: this field gives the distance in integer pixels from
the current pen position to the left-most pixel of
a glyph image WHEN IT IS A BITMAP. It is only valid
when the "format" field is set to
"ft_glyph_format_bitmap", for example, after calling
the new function FT_Render_Glyph.
bitmap_top: this field gives the distance in integer pixels from
the current pen position (located on the baseline) to
the top-most pixel of the glyph image WHEN IT IS A
BITMAP. Positive values correspond to upwards Y.
loader: this is a new private field for the glyph slot. Client
applications should not touch it..
- support for transforms and direct rendering in FT_Load_Glyph:
Most of the functionality found in <freetype/ftglyph.h> has been
moved to the core library. Hence, the following:
- a transform can be specified for a face through FT_Set_Transform.
this transform is applied by FT_Load_Glyph to scalable glyph images
(i.e. NOT TO BITMAPS) before the function returns, unless the
bit flag FT_LOAD_IGNORE_TRANSFORM was set in the load flags..
- once a glyph image has been loaded, it can be directly converted to
a bitmap by using the new FT_Render_Glyph function. Note that this
function takes the glyph image from the glyph slot, and converts
it to a bitmap whose properties are returned in "face.glyph.bitmap",
"face.glyph.bitmap_left" and "face.glyph.bitmap_top". The original
native image might be lost after the conversion.
- when using the new bit flag FT_LOAD_RENDER, the FT_Load_Glyph
and FT_Load_Char functions will call FT_Render_Glyph automatically
when needed.
2000-06-22 02:17:42 +02:00
|
|
|
|
2000-06-25 08:47:11 +02:00
|
|
|
/*************************************************************************/
|
|
|
|
/* */
|
|
|
|
/* <Function> */
|
|
|
|
/* T1_Done_Size_Hinter */
|
|
|
|
/* */
|
|
|
|
/* <Description> */
|
|
|
|
/* Releases a given size object's hinter structure. */
|
|
|
|
/* */
|
|
|
|
/* <Input> */
|
|
|
|
/* size :: A handle to the target size object. */
|
|
|
|
/* */
|
1999-12-17 00:11:37 +01:00
|
|
|
LOCAL_FUNC
|
2000-06-25 08:47:11 +02:00
|
|
|
void T1_Done_Size_Hinter( T1_Size size )
|
1999-12-17 00:11:37 +01:00
|
|
|
{
|
|
|
|
FT_Memory memory = size->root.face->memory;
|
|
|
|
|
2000-06-25 08:47:11 +02:00
|
|
|
|
1999-12-17 00:11:37 +01:00
|
|
|
FREE( size->hints );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2000-06-25 08:47:11 +02:00
|
|
|
/*************************************************************************/
|
|
|
|
/* */
|
|
|
|
/* <Function> */
|
|
|
|
/* T1_Reset_Size_Hinter */
|
|
|
|
/* */
|
|
|
|
/* <Description> */
|
|
|
|
/* Recomputes hinting information when a given size object has */
|
|
|
|
/* changed its resolutions/char sizes/pixel sizes. */
|
|
|
|
/* */
|
|
|
|
/* <InOut> */
|
|
|
|
/* size :: A handle to the size object. */
|
|
|
|
/* */
|
|
|
|
/* <Return> */
|
|
|
|
/* FreeType error code. 0 means success. */
|
|
|
|
/* */
|
1999-12-17 00:11:37 +01:00
|
|
|
LOCAL_FUNC
|
2000-06-16 21:34:52 +02:00
|
|
|
FT_Error T1_Reset_Size_Hinter( T1_Size size )
|
1999-12-17 00:11:37 +01:00
|
|
|
{
|
2000-06-25 08:47:11 +02:00
|
|
|
return t1_set_blue_zones( size ) || t1_set_snap_zones( size );
|
1999-12-17 00:11:37 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2000-06-25 08:47:11 +02:00
|
|
|
/*************************************************************************/
|
|
|
|
/* */
|
|
|
|
/* <Function> */
|
|
|
|
/* T1_New_Glyph_Hinter */
|
|
|
|
/* */
|
|
|
|
/* <Description> */
|
|
|
|
/* Allocates a new hinter structure for a given glyph slot. */
|
|
|
|
/* */
|
|
|
|
/* <InOut> */
|
|
|
|
/* glyph :: A handle to the target glyph slot. */
|
|
|
|
/* */
|
|
|
|
/* <Return> */
|
|
|
|
/* FreeType error code. 0 means success. */
|
|
|
|
/* */
|
1999-12-17 00:11:37 +01:00
|
|
|
LOCAL_FUNC
|
2000-06-16 21:34:52 +02:00
|
|
|
FT_Error T1_New_Glyph_Hinter( T1_GlyphSlot glyph )
|
1999-12-17 00:11:37 +01:00
|
|
|
{
|
|
|
|
FT_Memory memory = glyph->root.face->memory;
|
2000-05-17 01:44:38 +02:00
|
|
|
|
1999-12-17 00:11:37 +01:00
|
|
|
|
2000-06-25 08:47:11 +02:00
|
|
|
return MEM_Alloc( glyph->hints, sizeof ( *glyph->hints ) );
|
|
|
|
}
|
1999-12-17 00:11:37 +01:00
|
|
|
|
- MAJOR INTERNAL REDESIGN:
A lot of internal modifications have been performed lately on the
source in order to provide the following enhancements:
- more generic module support:
The FT_Module type is now defined to represent a handle to a given
module. The file <freetype/ftmodule.h> contains the FT_Module_Class
definition, as well as the module-loading public API
The FT_Driver type is still defined, and still represents a pointer
to a font driver. Note that FT_Add_Driver is replaced by FT_Add_Module,
FT_Get_Driver by FT_Get_Module, etc..
- support for generic glyph image types:
The FT_Renderer type is a pointer to a module used to perform various
operations on glyph image.
Each renderer is capable of handling images in a single format
(e.g. ft_glyph_format_outline). Its functions are used to:
- transform an glyph image
- render a glyph image into a bitmap
- return the control box (dimensions) of a given glyph image
The scan converters "ftraster.c" and "ftgrays.c" have been moved
to the new directory "src/renderer", and are used to provide two
default renderer modules.
One corresponds to the "standard" scan-converter, the other to the
"smooth" one.
The current renderer can be set through the new function
FT_Set_Renderer.
The old raster-related function FT_Set_Raster, FT_Get_Raster and
FT_Set_Raster_Mode have now disappeared, in favor of the new:
FT_Get_Renderer
FT_Set_Renderer
see the file <freetype/ftrender.h> for more details..
These changes were necessary to properly support different scalable
formats in the future, like bi-color glyphs, etc..
- glyph loader object:
A new internal object, called a 'glyph loader' has been introduced
in the base layer. It is used by all scalable format font drivers
to load glyphs and composites.
This object has been created to reduce the code size of each driver,
as each one of them basically re-implemented its functionality.
See <freetype/internal/ftobjs.h> and the FT_GlyphLoader type for
more information..
- FT_GlyphSlot had new fields:
In order to support extended features (see below), the FT_GlyphSlot
structure has a few new fields:
linearHoriAdvance: this field gives the linearly scaled (i.e.
scaled but unhinted) advance width for the glyph,
expressed as a 16.16 fixed pixel value. This
is useful to perform WYSIWYG text.
linearVertAdvance: this field gives the linearly scaled advance
height for the glyph (relevant in vertical glyph
layouts only). This is useful to perform
WYSIWYG text.
Note that the two above field replace the removed "metrics2" field
in the glyph slot.
advance: this field is a vector that gives the transformed
advance for the glyph. By default, it corresponds
to the advance width, unless FT_LOAD_VERTICAL_LAYOUT
was specified when calling FT_Load_Glyph or FT_Load_Char
bitmap_left: this field gives the distance in integer pixels from
the current pen position to the left-most pixel of
a glyph image WHEN IT IS A BITMAP. It is only valid
when the "format" field is set to
"ft_glyph_format_bitmap", for example, after calling
the new function FT_Render_Glyph.
bitmap_top: this field gives the distance in integer pixels from
the current pen position (located on the baseline) to
the top-most pixel of the glyph image WHEN IT IS A
BITMAP. Positive values correspond to upwards Y.
loader: this is a new private field for the glyph slot. Client
applications should not touch it..
- support for transforms and direct rendering in FT_Load_Glyph:
Most of the functionality found in <freetype/ftglyph.h> has been
moved to the core library. Hence, the following:
- a transform can be specified for a face through FT_Set_Transform.
this transform is applied by FT_Load_Glyph to scalable glyph images
(i.e. NOT TO BITMAPS) before the function returns, unless the
bit flag FT_LOAD_IGNORE_TRANSFORM was set in the load flags..
- once a glyph image has been loaded, it can be directly converted to
a bitmap by using the new FT_Render_Glyph function. Note that this
function takes the glyph image from the glyph slot, and converts
it to a bitmap whose properties are returned in "face.glyph.bitmap",
"face.glyph.bitmap_left" and "face.glyph.bitmap_top". The original
native image might be lost after the conversion.
- when using the new bit flag FT_LOAD_RENDER, the FT_Load_Glyph
and FT_Load_Char functions will call FT_Render_Glyph automatically
when needed.
2000-06-22 02:17:42 +02:00
|
|
|
|
2000-06-25 08:47:11 +02:00
|
|
|
/*************************************************************************/
|
|
|
|
/* */
|
|
|
|
/* <Function> */
|
|
|
|
/* T1_Done_Glyph_Hinter */
|
|
|
|
/* */
|
|
|
|
/* <Description> */
|
|
|
|
/* Releases a given glyph slot's hinter structure. */
|
|
|
|
/* */
|
|
|
|
/* <Input> */
|
|
|
|
/* glyph :: A handle to the glyph slot. */
|
|
|
|
/* */
|
1999-12-17 00:11:37 +01:00
|
|
|
LOCAL_FUNC
|
|
|
|
void T1_Done_Glyph_Hinter( T1_GlyphSlot glyph )
|
|
|
|
{
|
|
|
|
FT_Memory memory = glyph->root.face->memory;
|
|
|
|
|
2000-06-25 08:47:11 +02:00
|
|
|
|
1999-12-17 00:11:37 +01:00
|
|
|
FREE( glyph->hints );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2000-06-25 08:47:11 +02:00
|
|
|
/*************************************************************************/
|
|
|
|
/*************************************************************************/
|
|
|
|
/*************************************************************************/
|
|
|
|
/********** **********/
|
|
|
|
/********** HINTED GLYPH LOADER **********/
|
|
|
|
/********** **********/
|
|
|
|
/********** The following code is in charge of the first **********/
|
|
|
|
/********** and second pass when loading a single outline **********/
|
|
|
|
/********** **********/
|
|
|
|
/*************************************************************************/
|
|
|
|
/*************************************************************************/
|
|
|
|
/*************************************************************************/
|
1999-12-17 00:11:37 +01:00
|
|
|
|
|
|
|
|
|
|
|
static
|
2000-06-25 08:47:11 +02:00
|
|
|
FT_Error t1_hinter_ignore( void )
|
1999-12-17 00:11:37 +01:00
|
|
|
{
|
2000-06-25 08:47:11 +02:00
|
|
|
/* do nothing, used for `dotsection' which is unsupported for now */
|
1999-12-17 00:11:37 +01:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2000-06-25 08:47:11 +02:00
|
|
|
|
1999-12-17 00:11:37 +01:00
|
|
|
static
|
2000-06-25 08:47:11 +02:00
|
|
|
FT_Error t1_hinter_stem( T1_Builder* builder,
|
|
|
|
FT_Pos pos,
|
|
|
|
FT_Int width,
|
|
|
|
FT_Bool vertical )
|
1999-12-17 00:11:37 +01:00
|
|
|
{
|
|
|
|
T1_Stem_Table* stem_table;
|
|
|
|
T1_Stem_Hint* stems;
|
|
|
|
T1_Stem_Hint* cur_stem;
|
2000-06-16 21:34:52 +02:00
|
|
|
FT_Int min, max, n, num_stems;
|
|
|
|
FT_Bool new_stem;
|
1999-12-17 00:11:37 +01:00
|
|
|
T1_Glyph_Hints* hinter = builder->glyph->hints;
|
|
|
|
|
2000-06-25 08:47:11 +02:00
|
|
|
|
1999-12-17 00:11:37 +01:00
|
|
|
/* select the appropriate stem array */
|
|
|
|
stem_table = vertical ? &hinter->vert_stems : &hinter->hori_stems;
|
|
|
|
stems = stem_table->stems;
|
|
|
|
num_stems = stem_table->num_stems;
|
|
|
|
|
2000-06-08 01:06:10 +02:00
|
|
|
/* Compute minimum and maximum coord for the stem */
|
- MAJOR INTERNAL REDESIGN:
A lot of internal modifications have been performed lately on the
source in order to provide the following enhancements:
- more generic module support:
The FT_Module type is now defined to represent a handle to a given
module. The file <freetype/ftmodule.h> contains the FT_Module_Class
definition, as well as the module-loading public API
The FT_Driver type is still defined, and still represents a pointer
to a font driver. Note that FT_Add_Driver is replaced by FT_Add_Module,
FT_Get_Driver by FT_Get_Module, etc..
- support for generic glyph image types:
The FT_Renderer type is a pointer to a module used to perform various
operations on glyph image.
Each renderer is capable of handling images in a single format
(e.g. ft_glyph_format_outline). Its functions are used to:
- transform an glyph image
- render a glyph image into a bitmap
- return the control box (dimensions) of a given glyph image
The scan converters "ftraster.c" and "ftgrays.c" have been moved
to the new directory "src/renderer", and are used to provide two
default renderer modules.
One corresponds to the "standard" scan-converter, the other to the
"smooth" one.
The current renderer can be set through the new function
FT_Set_Renderer.
The old raster-related function FT_Set_Raster, FT_Get_Raster and
FT_Set_Raster_Mode have now disappeared, in favor of the new:
FT_Get_Renderer
FT_Set_Renderer
see the file <freetype/ftrender.h> for more details..
These changes were necessary to properly support different scalable
formats in the future, like bi-color glyphs, etc..
- glyph loader object:
A new internal object, called a 'glyph loader' has been introduced
in the base layer. It is used by all scalable format font drivers
to load glyphs and composites.
This object has been created to reduce the code size of each driver,
as each one of them basically re-implemented its functionality.
See <freetype/internal/ftobjs.h> and the FT_GlyphLoader type for
more information..
- FT_GlyphSlot had new fields:
In order to support extended features (see below), the FT_GlyphSlot
structure has a few new fields:
linearHoriAdvance: this field gives the linearly scaled (i.e.
scaled but unhinted) advance width for the glyph,
expressed as a 16.16 fixed pixel value. This
is useful to perform WYSIWYG text.
linearVertAdvance: this field gives the linearly scaled advance
height for the glyph (relevant in vertical glyph
layouts only). This is useful to perform
WYSIWYG text.
Note that the two above field replace the removed "metrics2" field
in the glyph slot.
advance: this field is a vector that gives the transformed
advance for the glyph. By default, it corresponds
to the advance width, unless FT_LOAD_VERTICAL_LAYOUT
was specified when calling FT_Load_Glyph or FT_Load_Char
bitmap_left: this field gives the distance in integer pixels from
the current pen position to the left-most pixel of
a glyph image WHEN IT IS A BITMAP. It is only valid
when the "format" field is set to
"ft_glyph_format_bitmap", for example, after calling
the new function FT_Render_Glyph.
bitmap_top: this field gives the distance in integer pixels from
the current pen position (located on the baseline) to
the top-most pixel of the glyph image WHEN IT IS A
BITMAP. Positive values correspond to upwards Y.
loader: this is a new private field for the glyph slot. Client
applications should not touch it..
- support for transforms and direct rendering in FT_Load_Glyph:
Most of the functionality found in <freetype/ftglyph.h> has been
moved to the core library. Hence, the following:
- a transform can be specified for a face through FT_Set_Transform.
this transform is applied by FT_Load_Glyph to scalable glyph images
(i.e. NOT TO BITMAPS) before the function returns, unless the
bit flag FT_LOAD_IGNORE_TRANSFORM was set in the load flags..
- once a glyph image has been loaded, it can be directly converted to
a bitmap by using the new FT_Render_Glyph function. Note that this
function takes the glyph image from the glyph slot, and converts
it to a bitmap whose properties are returned in "face.glyph.bitmap",
"face.glyph.bitmap_left" and "face.glyph.bitmap_top". The original
native image might be lost after the conversion.
- when using the new bit flag FT_LOAD_RENDER, the FT_Load_Glyph
and FT_Load_Char functions will call FT_Render_Glyph automatically
when needed.
2000-06-22 02:17:42 +02:00
|
|
|
min = pos + ( vertical
|
|
|
|
? builder->left_bearing.x
|
|
|
|
: builder->left_bearing.y );
|
1999-12-17 00:11:37 +01:00
|
|
|
|
|
|
|
if ( width >= 0 )
|
|
|
|
max = min + width;
|
|
|
|
else
|
|
|
|
{
|
2000-06-25 08:47:11 +02:00
|
|
|
/* a negative width indicates a `ghost' stem */
|
1999-12-17 00:11:37 +01:00
|
|
|
if ( width == -21 )
|
|
|
|
min += width;
|
|
|
|
|
|
|
|
max = min;
|
|
|
|
}
|
|
|
|
|
2000-07-03 09:09:09 +02:00
|
|
|
/* Now scan the array. If we find a stem with the same borders */
|
2000-06-25 08:47:11 +02:00
|
|
|
/* simply activate it. */
|
1999-12-17 00:11:37 +01:00
|
|
|
cur_stem = stems;
|
|
|
|
new_stem = 1;
|
|
|
|
|
|
|
|
for ( n = 0; n < num_stems; n++, cur_stem++ )
|
|
|
|
{
|
|
|
|
if ( cur_stem->min_edge.orus == min &&
|
|
|
|
cur_stem->max_edge.orus == max )
|
|
|
|
{
|
|
|
|
/* This stem is already in the table, simply activate it */
|
2000-06-25 08:47:11 +02:00
|
|
|
if ( ( cur_stem->hint_flags & T1_HINT_FLAG_ACTIVE ) == 0 )
|
1999-12-17 00:11:37 +01:00
|
|
|
{
|
2000-06-25 08:47:11 +02:00
|
|
|
cur_stem->hint_flags |= T1_HINT_FLAG_ACTIVE;
|
|
|
|
stem_table->num_active++;
|
1999-12-17 00:11:37 +01:00
|
|
|
}
|
|
|
|
new_stem = 0;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2000-07-03 09:09:09 +02:00
|
|
|
/* add a new stem to the array if necessary */
|
2000-06-25 08:47:11 +02:00
|
|
|
if ( new_stem )
|
1999-12-17 00:11:37 +01:00
|
|
|
{
|
2000-06-25 08:47:11 +02:00
|
|
|
if ( cur_stem >= stems + T1_HINTER_MAX_EDGES )
|
1999-12-17 00:11:37 +01:00
|
|
|
{
|
2000-06-25 08:47:11 +02:00
|
|
|
FT_ERROR(( "t1_hinter_stem: too many stems in glyph charstring\n" ));
|
1999-12-17 00:11:37 +01:00
|
|
|
return T1_Err_Syntax_Error;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* on the first pass, we record the stem, otherwise, this is */
|
2000-06-25 08:47:11 +02:00
|
|
|
/* a bug in the glyph loader! */
|
1999-12-17 00:11:37 +01:00
|
|
|
if ( builder->pass == 0 )
|
|
|
|
{
|
|
|
|
cur_stem->min_edge.orus = min;
|
|
|
|
cur_stem->max_edge.orus = max;
|
|
|
|
cur_stem->hint_flags = T1_HINT_FLAG_ACTIVE;
|
|
|
|
|
|
|
|
stem_table->num_stems++;
|
|
|
|
stem_table->num_active++;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2000-07-03 09:09:09 +02:00
|
|
|
FT_ERROR(( "t1_hinter_stem:" ));
|
|
|
|
FT_ERROR(( " fatal glyph loader bug -- pass2-stem\n" ));
|
1999-12-17 00:11:37 +01:00
|
|
|
return T1_Err_Syntax_Error;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return T1_Err_Ok;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static
|
2000-06-25 08:47:11 +02:00
|
|
|
FT_Error t1_hinter_stem3( T1_Builder* builder,
|
|
|
|
FT_Pos pos0,
|
|
|
|
FT_Int width0,
|
|
|
|
FT_Pos pos1,
|
|
|
|
FT_Int width1,
|
|
|
|
FT_Pos pos2,
|
|
|
|
FT_Int width2,
|
|
|
|
FT_Bool vertical )
|
1999-12-17 00:11:37 +01:00
|
|
|
{
|
2000-06-25 08:47:11 +02:00
|
|
|
/* For now, simply call `stem' 3 times */
|
1999-12-17 00:11:37 +01:00
|
|
|
return t1_hinter_stem( builder, pos0, width0, vertical ) ||
|
|
|
|
t1_hinter_stem( builder, pos1, width1, vertical ) ||
|
|
|
|
t1_hinter_stem( builder, pos2, width2, vertical );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static
|
2000-06-16 21:34:52 +02:00
|
|
|
FT_Error t1_hinter_changehints( T1_Builder* builder )
|
1999-12-17 00:11:37 +01:00
|
|
|
{
|
2000-06-16 21:34:52 +02:00
|
|
|
FT_Int dimension;
|
1999-12-17 00:11:37 +01:00
|
|
|
T1_Stem_Table* stem_table;
|
|
|
|
T1_Glyph_Hints* hinter = builder->glyph->hints;
|
|
|
|
|
2000-06-25 08:47:11 +02:00
|
|
|
|
|
|
|
/* If we are in the second pass of glyph hinting, we must */
|
|
|
|
/* call the function T1_Hint_Points() on the builder in order */
|
|
|
|
/* to force the fit the latest points to the pixel grid. */
|
1999-12-17 00:11:37 +01:00
|
|
|
if ( builder->pass == 1 )
|
|
|
|
T1_Hint_Points( builder );
|
|
|
|
|
|
|
|
/* Simply de-activate all hints in all arrays */
|
|
|
|
stem_table = &hinter->hori_stems;
|
|
|
|
|
|
|
|
for ( dimension = 2; dimension > 0; dimension-- )
|
|
|
|
{
|
|
|
|
T1_Stem_Hint* cur = stem_table->stems;
|
|
|
|
T1_Stem_Hint* limit = cur + stem_table->num_stems;
|
|
|
|
|
2000-06-25 08:47:11 +02:00
|
|
|
|
1999-12-17 00:11:37 +01:00
|
|
|
for ( ; cur < limit; cur++ )
|
|
|
|
cur->hint_flags &= ~T1_HINT_FLAG_ACTIVE;
|
|
|
|
|
|
|
|
stem_table->num_active = 0;
|
|
|
|
stem_table = &hinter->vert_stems;
|
|
|
|
}
|
|
|
|
|
|
|
|
return T1_Err_Ok;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const T1_Hinter_Funcs t1_hinter_funcs =
|
|
|
|
{
|
2000-06-25 08:47:11 +02:00
|
|
|
(T1_Hinter_ChangeHints)t1_hinter_changehints,
|
|
|
|
(T1_Hinter_DotSection) t1_hinter_ignore,
|
|
|
|
(T1_Hinter_Stem) t1_hinter_stem,
|
|
|
|
(T1_Hinter_Stem3) t1_hinter_stem3
|
1999-12-17 00:11:37 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2000-06-25 08:47:11 +02:00
|
|
|
/*************************************************************************/
|
|
|
|
/*************************************************************************/
|
|
|
|
/*************************************************************************/
|
|
|
|
/********** *********/
|
|
|
|
/********** *********/
|
|
|
|
/********** STEM HINTS MANAGEMENT *********/
|
|
|
|
/********** *********/
|
|
|
|
/********** The following code is in charge of computing *********/
|
|
|
|
/********** the placement of each scaled stem hint. *********/
|
|
|
|
/********** *********/
|
|
|
|
/*************************************************************************/
|
|
|
|
/*************************************************************************/
|
|
|
|
/*************************************************************************/
|
|
|
|
|
|
|
|
|
|
|
|
/*************************************************************************/
|
|
|
|
/* */
|
|
|
|
/* <Function> */
|
|
|
|
/* t1_sort_hints */
|
|
|
|
/* */
|
|
|
|
/* <Description> */
|
|
|
|
/* Sorta the list of active stems in increasing order, through the */
|
|
|
|
/* `sort' indexing table. */
|
|
|
|
/* */
|
|
|
|
/* <InOut> */
|
|
|
|
/* table :: A stem hints table. */
|
|
|
|
/* */
|
1999-12-17 00:11:37 +01:00
|
|
|
static
|
|
|
|
void t1_sort_hints( T1_Stem_Table* table )
|
|
|
|
{
|
2000-07-03 09:09:09 +02:00
|
|
|
FT_Int num_stems = table->num_stems;
|
|
|
|
FT_Int num_active = 0;
|
|
|
|
FT_Int* sort = table->sort;
|
|
|
|
T1_Stem_Hint* stems = table->stems;
|
2000-06-16 21:34:52 +02:00
|
|
|
FT_Int n;
|
1999-12-17 00:11:37 +01:00
|
|
|
|
2000-06-25 08:47:11 +02:00
|
|
|
|
1999-12-17 00:11:37 +01:00
|
|
|
/* record active stems in sort table */
|
|
|
|
for ( n = 0; n < num_stems; n++ )
|
|
|
|
{
|
|
|
|
if ( stems[n].hint_flags & T1_HINT_FLAG_ACTIVE )
|
|
|
|
sort[num_active++] = n;
|
|
|
|
}
|
|
|
|
|
2000-07-03 09:09:09 +02:00
|
|
|
/* Now sort the indices. There are usually very few stems, */
|
2000-06-25 08:47:11 +02:00
|
|
|
/* and they are pre-sorted in 90% cases, so we choose a */
|
|
|
|
/* simple bubble sort (quicksort would be slower). */
|
1999-12-17 00:11:37 +01:00
|
|
|
for ( n = 1; n < num_active; n++ )
|
|
|
|
{
|
2000-06-25 08:47:11 +02:00
|
|
|
FT_Int p = n - 1;
|
|
|
|
T1_Stem_Hint* cur = stems + sort[n];
|
|
|
|
|
1999-12-17 00:11:37 +01:00
|
|
|
|
|
|
|
do
|
|
|
|
{
|
2000-06-16 21:34:52 +02:00
|
|
|
FT_Int swap;
|
1999-12-17 00:11:37 +01:00
|
|
|
T1_Stem_Hint* prev = stems + sort[p];
|
|
|
|
|
2000-06-25 08:47:11 +02:00
|
|
|
|
|
|
|
/* note that by definition, the active stems cannot overlap */
|
|
|
|
/* so we simply compare their `min' to sort them (we could compare */
|
|
|
|
/* their max values also; this wouldn't change anything). */
|
1999-12-17 00:11:37 +01:00
|
|
|
if ( prev->min_edge.orus <= cur->min_edge.orus )
|
|
|
|
break;
|
|
|
|
|
|
|
|
/* swap elements */
|
2000-06-25 08:47:11 +02:00
|
|
|
swap = sort[p ];
|
|
|
|
sort[p ] = sort[p + 1];
|
|
|
|
sort[p + 1] = swap;
|
1999-12-17 00:11:37 +01:00
|
|
|
p--;
|
2000-07-03 09:09:09 +02:00
|
|
|
|
2000-06-25 08:47:11 +02:00
|
|
|
} while ( p >= 0 );
|
1999-12-17 00:11:37 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
table->num_active = num_active;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2000-06-25 08:47:11 +02:00
|
|
|
/*************************************************************************/
|
|
|
|
/* */
|
|
|
|
/* <Function> */
|
|
|
|
/* t1_hint_horizontal_stems */
|
|
|
|
/* */
|
|
|
|
/* <Description> */
|
|
|
|
/* Computes the location of each scaled horizontal stem hint. This */
|
|
|
|
/* takes care of the blue zones and the horizontal stem snap table. */
|
|
|
|
/* */
|
|
|
|
/* <Input> */
|
|
|
|
/* table :: The horizontal stem hints table. */
|
|
|
|
/* */
|
|
|
|
/* hints :: The current size's hint structure. */
|
|
|
|
/* */
|
|
|
|
/* blueShift :: The value of the /BlueShift as taken from the face */
|
|
|
|
/* object. */
|
|
|
|
/* */
|
|
|
|
/* scale :: The 16.16 scale used to convert outline units to */
|
|
|
|
/* 26.6 pixels. */
|
|
|
|
/* */
|
|
|
|
/* <Note> */
|
|
|
|
/* For now, all stems are hinted independently from each other. It */
|
|
|
|
/* might be necessary, for better performance, to introduce the */
|
|
|
|
/* notion of `controlled' hints describing things like counter-stems, */
|
|
|
|
/* stem3, as well as overlapping stems control. */
|
|
|
|
/* */
|
1999-12-17 00:11:37 +01:00
|
|
|
static
|
|
|
|
void t1_hint_horizontal_stems( T1_Stem_Table* table,
|
|
|
|
T1_Size_Hints* hints,
|
2000-06-16 21:34:52 +02:00
|
|
|
FT_Pos blueShift,
|
|
|
|
FT_Fixed scale )
|
1999-12-17 00:11:37 +01:00
|
|
|
{
|
|
|
|
T1_Stem_Hint* stem = table->stems;
|
|
|
|
T1_Stem_Hint* limit = stem + table->num_stems;
|
|
|
|
|
2000-06-25 08:47:11 +02:00
|
|
|
|
1999-12-17 00:11:37 +01:00
|
|
|
/* first of all, scale the blueShift */
|
2000-06-25 08:47:11 +02:00
|
|
|
blueShift = SCALE( blueShift );
|
1999-12-17 00:11:37 +01:00
|
|
|
|
|
|
|
/* then scan the horizontal stem table */
|
|
|
|
for ( ; stem < limit; stem++ )
|
|
|
|
{
|
2000-06-16 21:34:52 +02:00
|
|
|
FT_Pos bottom_orus = stem->min_edge.orus;
|
|
|
|
FT_Pos top_orus = stem->max_edge.orus;
|
1999-12-17 00:11:37 +01:00
|
|
|
|
2000-06-16 21:34:52 +02:00
|
|
|
FT_Pos top_pix = SCALE( top_orus );
|
|
|
|
FT_Pos bottom_pix = SCALE( bottom_orus );
|
|
|
|
FT_Pos width_pix = top_pix - bottom_pix;
|
1999-12-17 00:11:37 +01:00
|
|
|
|
2000-06-16 21:34:52 +02:00
|
|
|
FT_Pos bottom = bottom_pix;
|
|
|
|
FT_Pos top = top_pix;
|
|
|
|
FT_Int align = T1_ALIGN_NONE;
|
1999-12-17 00:11:37 +01:00
|
|
|
|
2000-06-25 08:47:11 +02:00
|
|
|
|
|
|
|
/*********************************************************************/
|
|
|
|
/* */
|
|
|
|
/* Snap pixel width if in stem snap range */
|
|
|
|
/* */
|
|
|
|
|
1999-12-17 00:11:37 +01:00
|
|
|
{
|
|
|
|
T1_Snap_Zone* zone = hints->snap_heights;
|
|
|
|
T1_Snap_Zone* zone_limit = zone + hints->num_snap_heights;
|
2000-06-25 08:47:11 +02:00
|
|
|
FT_Pos best_dist = 32000;
|
|
|
|
T1_Snap_Zone* best_zone = 0;
|
|
|
|
|
1999-12-17 00:11:37 +01:00
|
|
|
|
|
|
|
for ( ; zone < zone_limit; zone++ )
|
|
|
|
{
|
2000-06-16 21:34:52 +02:00
|
|
|
FT_Pos dist;
|
2000-05-17 01:44:38 +02:00
|
|
|
|
2000-06-25 08:47:11 +02:00
|
|
|
|
|
|
|
dist = width_pix - zone->min;
|
|
|
|
if ( dist < 0 )
|
|
|
|
dist = -dist;
|
|
|
|
if ( dist < best_dist )
|
1999-12-17 00:11:37 +01:00
|
|
|
{
|
2000-04-04 20:21:45 +02:00
|
|
|
best_zone = zone;
|
|
|
|
best_dist = dist;
|
|
|
|
}
|
|
|
|
}
|
2000-05-17 01:44:38 +02:00
|
|
|
|
2000-06-25 08:47:11 +02:00
|
|
|
if ( best_zone )
|
2000-04-04 20:21:45 +02:00
|
|
|
{
|
2000-06-25 08:47:11 +02:00
|
|
|
if ( width_pix > best_zone->pix )
|
2000-04-04 20:21:45 +02:00
|
|
|
{
|
|
|
|
width_pix -= 0x20;
|
2000-06-25 08:47:11 +02:00
|
|
|
if ( width_pix < best_zone->pix )
|
2000-04-04 20:21:45 +02:00
|
|
|
width_pix = best_zone->pix;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
width_pix += 0x20;
|
2000-06-25 08:47:11 +02:00
|
|
|
if ( width_pix > best_zone->pix )
|
2000-04-04 20:21:45 +02:00
|
|
|
width_pix = best_zone->pix;
|
1999-12-17 00:11:37 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2000-06-25 08:47:11 +02:00
|
|
|
/*********************************************************************/
|
|
|
|
/* */
|
|
|
|
/* round width - minimum 1 pixel if this isn't a ghost stem */
|
|
|
|
/* */
|
|
|
|
|
1999-12-17 00:11:37 +01:00
|
|
|
if ( width_pix > 0 )
|
2000-06-25 08:47:11 +02:00
|
|
|
width_pix = width_pix < ONE_PIXEL ? ONE_PIXEL : ROUND( width_pix );
|
|
|
|
|
1999-12-17 00:11:37 +01:00
|
|
|
|
2000-06-25 08:47:11 +02:00
|
|
|
/*********************************************************************/
|
|
|
|
/* */
|
|
|
|
/* Now check for bottom blue zones alignement */
|
|
|
|
/* */
|
1999-12-17 00:11:37 +01:00
|
|
|
|
|
|
|
{
|
2000-06-16 21:34:52 +02:00
|
|
|
FT_Int num_blues = hints->num_bottom_zones;
|
1999-12-17 00:11:37 +01:00
|
|
|
T1_Snap_Zone* blue = hints->blue_zones;
|
|
|
|
T1_Snap_Zone* blue_limit = blue + num_blues;
|
|
|
|
|
2000-06-25 08:47:11 +02:00
|
|
|
|
1999-12-17 00:11:37 +01:00
|
|
|
for ( ; blue < blue_limit; blue++ )
|
|
|
|
{
|
|
|
|
if ( bottom_pix < blue->min )
|
|
|
|
break;
|
|
|
|
|
|
|
|
if ( bottom_pix <= blue->max )
|
|
|
|
{
|
|
|
|
align = T1_ALIGN_BOTTOM;
|
|
|
|
bottom = ROUND( blue->pix );
|
|
|
|
|
2000-06-25 08:47:11 +02:00
|
|
|
/* implement blue shift */
|
|
|
|
if ( !hints->supress_overshoots )
|
1999-12-17 00:11:37 +01:00
|
|
|
{
|
2000-06-16 21:34:52 +02:00
|
|
|
FT_Pos delta = blue->pix - bottom_pix;
|
2000-05-17 01:44:38 +02:00
|
|
|
|
2000-06-25 08:47:11 +02:00
|
|
|
|
|
|
|
delta = delta < blueShift ? 0 : ROUND( delta );
|
1999-12-17 00:11:37 +01:00
|
|
|
bottom -= delta;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2000-06-25 08:47:11 +02:00
|
|
|
/*********************************************************************/
|
|
|
|
/* */
|
|
|
|
/* check for top blue zones alignement */
|
|
|
|
/* */
|
1999-12-17 00:11:37 +01:00
|
|
|
|
|
|
|
{
|
2000-06-16 21:34:52 +02:00
|
|
|
FT_Int num_blues = hints->num_blue_zones -
|
1999-12-17 00:11:37 +01:00
|
|
|
hints->num_bottom_zones;
|
|
|
|
|
|
|
|
T1_Snap_Zone* blue = hints->blue_zones +
|
|
|
|
hints->num_bottom_zones;
|
|
|
|
|
|
|
|
T1_Snap_Zone* blue_limit = blue + num_blues;
|
|
|
|
|
2000-06-25 08:47:11 +02:00
|
|
|
|
1999-12-17 00:11:37 +01:00
|
|
|
for ( ; blue < blue_limit; blue++ )
|
|
|
|
{
|
|
|
|
if ( top_pix < blue->min )
|
|
|
|
break;
|
|
|
|
|
|
|
|
if ( top_pix <= blue->max )
|
|
|
|
{
|
2000-06-25 08:47:11 +02:00
|
|
|
align |= T1_ALIGN_TOP;
|
|
|
|
top = ROUND( blue->pix );
|
1999-12-17 00:11:37 +01:00
|
|
|
|
2000-06-25 08:47:11 +02:00
|
|
|
/* implement blue shift */
|
|
|
|
if ( !hints->supress_overshoots )
|
1999-12-17 00:11:37 +01:00
|
|
|
{
|
2000-06-16 21:34:52 +02:00
|
|
|
FT_Pos delta = top - blue->pix;
|
2000-05-17 01:44:38 +02:00
|
|
|
|
2000-06-25 08:47:11 +02:00
|
|
|
|
|
|
|
delta = delta < blueShift ? 0 : ROUND( delta );
|
1999-12-17 00:11:37 +01:00
|
|
|
top += delta;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2000-06-25 08:47:11 +02:00
|
|
|
/*********************************************************************/
|
|
|
|
/* */
|
|
|
|
/* compute the hinted stem position, according to its alignment */
|
|
|
|
/* */
|
1999-12-17 00:11:37 +01:00
|
|
|
|
2000-06-25 08:47:11 +02:00
|
|
|
switch ( align )
|
1999-12-17 00:11:37 +01:00
|
|
|
{
|
2000-06-25 08:47:11 +02:00
|
|
|
case T1_ALIGN_BOTTOM: /* bottom zone alignment */
|
|
|
|
bottom_pix = bottom;
|
|
|
|
top_pix = bottom + width_pix;
|
|
|
|
break;
|
2000-05-17 01:44:38 +02:00
|
|
|
|
2000-06-25 08:47:11 +02:00
|
|
|
case T1_ALIGN_TOP: /* top zone alignment */
|
|
|
|
top_pix = top;
|
|
|
|
bottom_pix = top - width_pix;
|
|
|
|
break;
|
1999-12-17 00:11:37 +01:00
|
|
|
|
2000-06-25 08:47:11 +02:00
|
|
|
case T1_ALIGN_BOTH: /* bottom+top zone alignment */
|
|
|
|
bottom_pix = bottom;
|
|
|
|
top_pix = top;
|
|
|
|
break;
|
2000-05-17 01:44:38 +02:00
|
|
|
|
2000-06-25 08:47:11 +02:00
|
|
|
default: /* no alignment */
|
2000-07-03 09:09:09 +02:00
|
|
|
/* XXX TODO: Add management of controlled stems */
|
2000-06-25 08:47:11 +02:00
|
|
|
bottom = ( SCALE( bottom_orus + top_orus ) - width_pix ) / 2;
|
- MAJOR INTERNAL REDESIGN:
A lot of internal modifications have been performed lately on the
source in order to provide the following enhancements:
- more generic module support:
The FT_Module type is now defined to represent a handle to a given
module. The file <freetype/ftmodule.h> contains the FT_Module_Class
definition, as well as the module-loading public API
The FT_Driver type is still defined, and still represents a pointer
to a font driver. Note that FT_Add_Driver is replaced by FT_Add_Module,
FT_Get_Driver by FT_Get_Module, etc..
- support for generic glyph image types:
The FT_Renderer type is a pointer to a module used to perform various
operations on glyph image.
Each renderer is capable of handling images in a single format
(e.g. ft_glyph_format_outline). Its functions are used to:
- transform an glyph image
- render a glyph image into a bitmap
- return the control box (dimensions) of a given glyph image
The scan converters "ftraster.c" and "ftgrays.c" have been moved
to the new directory "src/renderer", and are used to provide two
default renderer modules.
One corresponds to the "standard" scan-converter, the other to the
"smooth" one.
The current renderer can be set through the new function
FT_Set_Renderer.
The old raster-related function FT_Set_Raster, FT_Get_Raster and
FT_Set_Raster_Mode have now disappeared, in favor of the new:
FT_Get_Renderer
FT_Set_Renderer
see the file <freetype/ftrender.h> for more details..
These changes were necessary to properly support different scalable
formats in the future, like bi-color glyphs, etc..
- glyph loader object:
A new internal object, called a 'glyph loader' has been introduced
in the base layer. It is used by all scalable format font drivers
to load glyphs and composites.
This object has been created to reduce the code size of each driver,
as each one of them basically re-implemented its functionality.
See <freetype/internal/ftobjs.h> and the FT_GlyphLoader type for
more information..
- FT_GlyphSlot had new fields:
In order to support extended features (see below), the FT_GlyphSlot
structure has a few new fields:
linearHoriAdvance: this field gives the linearly scaled (i.e.
scaled but unhinted) advance width for the glyph,
expressed as a 16.16 fixed pixel value. This
is useful to perform WYSIWYG text.
linearVertAdvance: this field gives the linearly scaled advance
height for the glyph (relevant in vertical glyph
layouts only). This is useful to perform
WYSIWYG text.
Note that the two above field replace the removed "metrics2" field
in the glyph slot.
advance: this field is a vector that gives the transformed
advance for the glyph. By default, it corresponds
to the advance width, unless FT_LOAD_VERTICAL_LAYOUT
was specified when calling FT_Load_Glyph or FT_Load_Char
bitmap_left: this field gives the distance in integer pixels from
the current pen position to the left-most pixel of
a glyph image WHEN IT IS A BITMAP. It is only valid
when the "format" field is set to
"ft_glyph_format_bitmap", for example, after calling
the new function FT_Render_Glyph.
bitmap_top: this field gives the distance in integer pixels from
the current pen position (located on the baseline) to
the top-most pixel of the glyph image WHEN IT IS A
BITMAP. Positive values correspond to upwards Y.
loader: this is a new private field for the glyph slot. Client
applications should not touch it..
- support for transforms and direct rendering in FT_Load_Glyph:
Most of the functionality found in <freetype/ftglyph.h> has been
moved to the core library. Hence, the following:
- a transform can be specified for a face through FT_Set_Transform.
this transform is applied by FT_Load_Glyph to scalable glyph images
(i.e. NOT TO BITMAPS) before the function returns, unless the
bit flag FT_LOAD_IGNORE_TRANSFORM was set in the load flags..
- once a glyph image has been loaded, it can be directly converted to
a bitmap by using the new FT_Render_Glyph function. Note that this
function takes the glyph image from the glyph slot, and converts
it to a bitmap whose properties are returned in "face.glyph.bitmap",
"face.glyph.bitmap_left" and "face.glyph.bitmap_top". The original
native image might be lost after the conversion.
- when using the new bit flag FT_LOAD_RENDER, the FT_Load_Glyph
and FT_Load_Char functions will call FT_Render_Glyph automatically
when needed.
2000-06-22 02:17:42 +02:00
|
|
|
|
2000-06-25 08:47:11 +02:00
|
|
|
bottom_pix = ROUND( bottom );
|
|
|
|
top_pix = bottom_pix + width_pix;
|
1999-12-17 00:11:37 +01:00
|
|
|
}
|
2000-05-17 01:44:38 +02:00
|
|
|
|
1999-12-17 00:11:37 +01:00
|
|
|
stem->min_edge.pix = bottom_pix;
|
|
|
|
stem->max_edge.pix = top_pix;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2000-06-25 08:47:11 +02:00
|
|
|
/*************************************************************************/
|
|
|
|
/* */
|
|
|
|
/* <Function> */
|
|
|
|
/* t1_hint_vertical_stems */
|
|
|
|
/* */
|
|
|
|
/* <Description> */
|
|
|
|
/* Computes the location of each scaled vertical stem hint. This */
|
|
|
|
/* takes care of the vertical stem snap table. */
|
|
|
|
/* */
|
|
|
|
/* <Input> */
|
|
|
|
/* table :: The vertical stem hints table. */
|
|
|
|
/* hints :: The current size's hint structure. */
|
|
|
|
/* scale :: The 16.16 scale used to convert outline units to */
|
|
|
|
/* 26.6 pixels. */
|
|
|
|
/* */
|
|
|
|
/* <Note> */
|
|
|
|
/* For now, all stems are hinted independently from each other. It */
|
|
|
|
/* might be necessary, for better performance, to introduce the */
|
|
|
|
/* notion of `controlled' hints describing things like counter-stems, */
|
|
|
|
/* stem3 as well as overlapping stems control. */
|
|
|
|
/* */
|
1999-12-17 00:11:37 +01:00
|
|
|
static
|
|
|
|
void t1_hint_vertical_stems( T1_Stem_Table* table,
|
|
|
|
T1_Size_Hints* hints,
|
2000-06-16 21:34:52 +02:00
|
|
|
FT_Fixed scale )
|
1999-12-17 00:11:37 +01:00
|
|
|
{
|
|
|
|
T1_Stem_Hint* stem = table->stems;
|
|
|
|
T1_Stem_Hint* limit = stem + table->num_stems;
|
|
|
|
|
2000-06-25 08:47:11 +02:00
|
|
|
|
1999-12-17 00:11:37 +01:00
|
|
|
for ( ; stem < limit; stem++ )
|
|
|
|
{
|
2000-06-16 21:34:52 +02:00
|
|
|
FT_Pos stem_left = stem->min_edge.orus;
|
|
|
|
FT_Pos stem_right = stem->max_edge.orus;
|
|
|
|
FT_Pos width_pix, left;
|
1999-12-17 00:11:37 +01:00
|
|
|
|
2000-06-25 08:47:11 +02:00
|
|
|
|
1999-12-17 00:11:37 +01:00
|
|
|
width_pix = SCALE( stem_right - stem_left );
|
|
|
|
|
|
|
|
/* Snap pixel width if in stem snap range */
|
|
|
|
{
|
2000-04-04 20:21:45 +02:00
|
|
|
T1_Snap_Zone* zone = hints->snap_heights;
|
|
|
|
T1_Snap_Zone* zone_limit = zone + hints->num_snap_heights;
|
2000-06-25 08:47:11 +02:00
|
|
|
FT_Pos best_dist = 32000;
|
|
|
|
T1_Snap_Zone* best_zone = 0;
|
|
|
|
|
1999-12-17 00:11:37 +01:00
|
|
|
|
|
|
|
for ( ; zone < zone_limit; zone++ )
|
|
|
|
{
|
2000-06-16 21:34:52 +02:00
|
|
|
FT_Pos dist;
|
2000-05-17 01:44:38 +02:00
|
|
|
|
2000-06-25 08:47:11 +02:00
|
|
|
|
|
|
|
dist = width_pix - zone->min;
|
|
|
|
if ( dist < 0 )
|
|
|
|
dist = -dist;
|
|
|
|
if ( dist < best_dist )
|
1999-12-17 00:11:37 +01:00
|
|
|
{
|
2000-04-04 20:21:45 +02:00
|
|
|
best_zone = zone;
|
|
|
|
best_dist = dist;
|
|
|
|
}
|
|
|
|
}
|
2000-05-17 01:44:38 +02:00
|
|
|
|
2000-06-25 08:47:11 +02:00
|
|
|
if ( best_zone )
|
2000-04-04 20:21:45 +02:00
|
|
|
{
|
2000-06-25 08:47:11 +02:00
|
|
|
if ( width_pix > best_zone->pix )
|
2000-04-04 20:21:45 +02:00
|
|
|
{
|
|
|
|
width_pix -= 0x20;
|
2000-06-25 08:47:11 +02:00
|
|
|
if ( width_pix < best_zone->pix )
|
2000-04-04 20:21:45 +02:00
|
|
|
width_pix = best_zone->pix;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
width_pix += 0x20;
|
2000-06-25 08:47:11 +02:00
|
|
|
if ( width_pix > best_zone->pix )
|
2000-04-04 20:21:45 +02:00
|
|
|
width_pix = best_zone->pix;
|
1999-12-17 00:11:37 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2000-05-17 01:44:38 +02:00
|
|
|
|
1999-12-17 00:11:37 +01:00
|
|
|
/* round width - minimum 1 pixel if this isn't a ghost stem */
|
|
|
|
if ( width_pix > 0 )
|
2000-06-25 08:47:11 +02:00
|
|
|
width_pix = width_pix < ONE_PIXEL ? ONE_PIXEL
|
|
|
|
: ROUND( width_pix );
|
- MAJOR INTERNAL REDESIGN:
A lot of internal modifications have been performed lately on the
source in order to provide the following enhancements:
- more generic module support:
The FT_Module type is now defined to represent a handle to a given
module. The file <freetype/ftmodule.h> contains the FT_Module_Class
definition, as well as the module-loading public API
The FT_Driver type is still defined, and still represents a pointer
to a font driver. Note that FT_Add_Driver is replaced by FT_Add_Module,
FT_Get_Driver by FT_Get_Module, etc..
- support for generic glyph image types:
The FT_Renderer type is a pointer to a module used to perform various
operations on glyph image.
Each renderer is capable of handling images in a single format
(e.g. ft_glyph_format_outline). Its functions are used to:
- transform an glyph image
- render a glyph image into a bitmap
- return the control box (dimensions) of a given glyph image
The scan converters "ftraster.c" and "ftgrays.c" have been moved
to the new directory "src/renderer", and are used to provide two
default renderer modules.
One corresponds to the "standard" scan-converter, the other to the
"smooth" one.
The current renderer can be set through the new function
FT_Set_Renderer.
The old raster-related function FT_Set_Raster, FT_Get_Raster and
FT_Set_Raster_Mode have now disappeared, in favor of the new:
FT_Get_Renderer
FT_Set_Renderer
see the file <freetype/ftrender.h> for more details..
These changes were necessary to properly support different scalable
formats in the future, like bi-color glyphs, etc..
- glyph loader object:
A new internal object, called a 'glyph loader' has been introduced
in the base layer. It is used by all scalable format font drivers
to load glyphs and composites.
This object has been created to reduce the code size of each driver,
as each one of them basically re-implemented its functionality.
See <freetype/internal/ftobjs.h> and the FT_GlyphLoader type for
more information..
- FT_GlyphSlot had new fields:
In order to support extended features (see below), the FT_GlyphSlot
structure has a few new fields:
linearHoriAdvance: this field gives the linearly scaled (i.e.
scaled but unhinted) advance width for the glyph,
expressed as a 16.16 fixed pixel value. This
is useful to perform WYSIWYG text.
linearVertAdvance: this field gives the linearly scaled advance
height for the glyph (relevant in vertical glyph
layouts only). This is useful to perform
WYSIWYG text.
Note that the two above field replace the removed "metrics2" field
in the glyph slot.
advance: this field is a vector that gives the transformed
advance for the glyph. By default, it corresponds
to the advance width, unless FT_LOAD_VERTICAL_LAYOUT
was specified when calling FT_Load_Glyph or FT_Load_Char
bitmap_left: this field gives the distance in integer pixels from
the current pen position to the left-most pixel of
a glyph image WHEN IT IS A BITMAP. It is only valid
when the "format" field is set to
"ft_glyph_format_bitmap", for example, after calling
the new function FT_Render_Glyph.
bitmap_top: this field gives the distance in integer pixels from
the current pen position (located on the baseline) to
the top-most pixel of the glyph image WHEN IT IS A
BITMAP. Positive values correspond to upwards Y.
loader: this is a new private field for the glyph slot. Client
applications should not touch it..
- support for transforms and direct rendering in FT_Load_Glyph:
Most of the functionality found in <freetype/ftglyph.h> has been
moved to the core library. Hence, the following:
- a transform can be specified for a face through FT_Set_Transform.
this transform is applied by FT_Load_Glyph to scalable glyph images
(i.e. NOT TO BITMAPS) before the function returns, unless the
bit flag FT_LOAD_IGNORE_TRANSFORM was set in the load flags..
- once a glyph image has been loaded, it can be directly converted to
a bitmap by using the new FT_Render_Glyph function. Note that this
function takes the glyph image from the glyph slot, and converts
it to a bitmap whose properties are returned in "face.glyph.bitmap",
"face.glyph.bitmap_left" and "face.glyph.bitmap_top". The original
native image might be lost after the conversion.
- when using the new bit flag FT_LOAD_RENDER, the FT_Load_Glyph
and FT_Load_Char functions will call FT_Render_Glyph automatically
when needed.
2000-06-22 02:17:42 +02:00
|
|
|
|
|
|
|
/* now place the snapped and rounded stem */
|
1999-12-17 00:11:37 +01:00
|
|
|
|
2000-07-03 09:09:09 +02:00
|
|
|
/* XXX TODO: implement controlled stems for the overlapping */
|
|
|
|
/* cases */
|
1999-12-17 00:11:37 +01:00
|
|
|
|
2000-06-25 08:47:11 +02:00
|
|
|
left = ( SCALE( stem_left + stem_right ) - width_pix ) / 2;
|
1999-12-17 00:11:37 +01:00
|
|
|
|
2000-06-25 08:47:11 +02:00
|
|
|
stem->min_edge.pix = ROUND( left );
|
1999-12-17 00:11:37 +01:00
|
|
|
stem->max_edge.pix = stem->min_edge.pix + width_pix;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2000-06-25 08:47:11 +02:00
|
|
|
/*************************************************************************/
|
|
|
|
/* */
|
|
|
|
/* <Function> */
|
|
|
|
/* t1_hint_point */
|
|
|
|
/* */
|
|
|
|
/* <Description> */
|
|
|
|
/* Grid-fit a coordinate with regards to a given stem hints table. */
|
|
|
|
/* */
|
|
|
|
/* <Input> */
|
|
|
|
/* table :: The source stem hints table. */
|
|
|
|
/* coord :: The original coordinate, expressed in font units. */
|
|
|
|
/* scale :: The 16.16 scale used to convert font units into */
|
|
|
|
/* 26.6 pixels. */
|
|
|
|
/* */
|
|
|
|
/* <Return> */
|
|
|
|
/* The hinted/scaled value in 26.6 pixels. */
|
|
|
|
/* */
|
|
|
|
/* <Note> */
|
|
|
|
/* For now, all stems are hinted independently from each other. It */
|
|
|
|
/* might be necessary, for better performance, to introduce the */
|
|
|
|
/* notion of `controlled' hints describing things like counter-stems, */
|
|
|
|
/* stem3 as well as overlapping stems control. */
|
|
|
|
/* */
|
1999-12-17 00:11:37 +01:00
|
|
|
static
|
2000-06-16 21:34:52 +02:00
|
|
|
FT_Pos t1_hint_point( T1_Stem_Table* table,
|
|
|
|
FT_Pos coord,
|
|
|
|
FT_Fixed scale )
|
1999-12-17 00:11:37 +01:00
|
|
|
{
|
2000-06-16 21:34:52 +02:00
|
|
|
FT_Int num_active = table->num_active;
|
|
|
|
FT_Int n;
|
1999-12-17 00:11:37 +01:00
|
|
|
T1_Stem_Hint* prev = 0;
|
|
|
|
T1_Stem_Hint* cur = 0;
|
|
|
|
T1_Edge* min;
|
|
|
|
T1_Edge* max;
|
2000-06-16 21:34:52 +02:00
|
|
|
FT_Pos delta;
|
1999-12-17 00:11:37 +01:00
|
|
|
|
2000-06-25 08:47:11 +02:00
|
|
|
|
1999-12-17 00:11:37 +01:00
|
|
|
/* only hint when there is at least one stem defined */
|
2000-06-25 08:47:11 +02:00
|
|
|
if ( num_active <= 0 )
|
|
|
|
return SCALE( coord );
|
1999-12-17 00:11:37 +01:00
|
|
|
|
|
|
|
/* scan the stem table to determine placement of coordinate */
|
|
|
|
/* relative to the list of sorted and stems */
|
|
|
|
for ( n = 0; n < num_active; n++, prev = cur )
|
|
|
|
{
|
|
|
|
cur = table->stems + table->sort[n];
|
|
|
|
|
2000-06-25 08:47:11 +02:00
|
|
|
/* is it on the left of the current edge? */
|
1999-12-17 00:11:37 +01:00
|
|
|
delta = cur->min_edge.orus - coord;
|
2000-06-25 08:47:11 +02:00
|
|
|
if ( delta == 0 )
|
|
|
|
return cur->min_edge.pix;
|
1999-12-17 00:11:37 +01:00
|
|
|
|
2000-06-25 08:47:11 +02:00
|
|
|
if ( delta > 0 )
|
1999-12-17 00:11:37 +01:00
|
|
|
{
|
|
|
|
/* if this is the left of the first edge, simply shift */
|
2000-06-25 08:47:11 +02:00
|
|
|
if ( !prev )
|
|
|
|
return cur->min_edge.pix - SCALE( delta );
|
1999-12-17 00:11:37 +01:00
|
|
|
|
|
|
|
/* otherwise, interpolate between the maximum of the */
|
|
|
|
/* previous stem, and the minimum of the current one */
|
|
|
|
min = &prev->max_edge;
|
|
|
|
max = &cur->min_edge;
|
2000-06-25 08:47:11 +02:00
|
|
|
|
1999-12-17 00:11:37 +01:00
|
|
|
goto Interpolate;
|
|
|
|
}
|
|
|
|
|
2000-06-25 08:47:11 +02:00
|
|
|
/* is it within the current edge? */
|
1999-12-17 00:11:37 +01:00
|
|
|
delta = cur->max_edge.orus - coord;
|
2000-06-25 08:47:11 +02:00
|
|
|
if ( delta == 0 )
|
|
|
|
return cur->max_edge.pix;
|
1999-12-17 00:11:37 +01:00
|
|
|
|
2000-06-25 08:47:11 +02:00
|
|
|
if ( delta > 0 )
|
1999-12-17 00:11:37 +01:00
|
|
|
{
|
|
|
|
/* interpolate within the stem */
|
|
|
|
min = &cur->min_edge;
|
|
|
|
max = &cur->max_edge;
|
2000-06-25 08:47:11 +02:00
|
|
|
|
1999-12-17 00:11:37 +01:00
|
|
|
goto Interpolate;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* apparently, this coordinate is on the right of the last stem */
|
|
|
|
delta = coord - cur->max_edge.orus;
|
2000-06-25 08:47:11 +02:00
|
|
|
return cur->max_edge.pix + SCALE( delta );
|
1999-12-17 00:11:37 +01:00
|
|
|
|
|
|
|
Interpolate:
|
2000-06-25 08:47:11 +02:00
|
|
|
return min->pix + FT_MulDiv( coord - min->orus,
|
|
|
|
max->pix - min->pix,
|
|
|
|
max->orus - min->orus );
|
1999-12-17 00:11:37 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2000-06-25 08:47:11 +02:00
|
|
|
/*************************************************************************/
|
|
|
|
/* */
|
|
|
|
/* <Function> */
|
|
|
|
/* T1_Hint_Points */
|
|
|
|
/* */
|
|
|
|
/* <Description> */
|
|
|
|
/* This function grid-fits several points in a given Type 1 builder */
|
|
|
|
/* at once. */
|
|
|
|
/* */
|
|
|
|
/* <Input> */
|
|
|
|
/* builder :: A handle to target Type 1 builder. */
|
|
|
|
/* */
|
1999-12-17 00:11:37 +01:00
|
|
|
LOCAL_FUNC
|
|
|
|
void T1_Hint_Points( T1_Builder* builder )
|
|
|
|
{
|
2000-06-16 21:34:52 +02:00
|
|
|
FT_Int first = builder->hint_point;
|
2000-06-25 08:47:11 +02:00
|
|
|
FT_Int last = builder->current->n_points - 1;
|
1999-12-17 00:11:37 +01:00
|
|
|
|
|
|
|
T1_Size size = builder->size;
|
2000-06-16 21:34:52 +02:00
|
|
|
FT_Fixed scale_x = size->root.metrics.x_scale;
|
|
|
|
FT_Fixed scale_y = size->root.metrics.y_scale;
|
1999-12-17 00:11:37 +01:00
|
|
|
|
|
|
|
T1_Glyph_Hints* hints = builder->glyph->hints;
|
|
|
|
T1_Stem_Table* hori_stems = &hints->hori_stems;
|
|
|
|
T1_Stem_Table* vert_stems = &hints->vert_stems;
|
|
|
|
|
- MAJOR INTERNAL REDESIGN:
A lot of internal modifications have been performed lately on the
source in order to provide the following enhancements:
- more generic module support:
The FT_Module type is now defined to represent a handle to a given
module. The file <freetype/ftmodule.h> contains the FT_Module_Class
definition, as well as the module-loading public API
The FT_Driver type is still defined, and still represents a pointer
to a font driver. Note that FT_Add_Driver is replaced by FT_Add_Module,
FT_Get_Driver by FT_Get_Module, etc..
- support for generic glyph image types:
The FT_Renderer type is a pointer to a module used to perform various
operations on glyph image.
Each renderer is capable of handling images in a single format
(e.g. ft_glyph_format_outline). Its functions are used to:
- transform an glyph image
- render a glyph image into a bitmap
- return the control box (dimensions) of a given glyph image
The scan converters "ftraster.c" and "ftgrays.c" have been moved
to the new directory "src/renderer", and are used to provide two
default renderer modules.
One corresponds to the "standard" scan-converter, the other to the
"smooth" one.
The current renderer can be set through the new function
FT_Set_Renderer.
The old raster-related function FT_Set_Raster, FT_Get_Raster and
FT_Set_Raster_Mode have now disappeared, in favor of the new:
FT_Get_Renderer
FT_Set_Renderer
see the file <freetype/ftrender.h> for more details..
These changes were necessary to properly support different scalable
formats in the future, like bi-color glyphs, etc..
- glyph loader object:
A new internal object, called a 'glyph loader' has been introduced
in the base layer. It is used by all scalable format font drivers
to load glyphs and composites.
This object has been created to reduce the code size of each driver,
as each one of them basically re-implemented its functionality.
See <freetype/internal/ftobjs.h> and the FT_GlyphLoader type for
more information..
- FT_GlyphSlot had new fields:
In order to support extended features (see below), the FT_GlyphSlot
structure has a few new fields:
linearHoriAdvance: this field gives the linearly scaled (i.e.
scaled but unhinted) advance width for the glyph,
expressed as a 16.16 fixed pixel value. This
is useful to perform WYSIWYG text.
linearVertAdvance: this field gives the linearly scaled advance
height for the glyph (relevant in vertical glyph
layouts only). This is useful to perform
WYSIWYG text.
Note that the two above field replace the removed "metrics2" field
in the glyph slot.
advance: this field is a vector that gives the transformed
advance for the glyph. By default, it corresponds
to the advance width, unless FT_LOAD_VERTICAL_LAYOUT
was specified when calling FT_Load_Glyph or FT_Load_Char
bitmap_left: this field gives the distance in integer pixels from
the current pen position to the left-most pixel of
a glyph image WHEN IT IS A BITMAP. It is only valid
when the "format" field is set to
"ft_glyph_format_bitmap", for example, after calling
the new function FT_Render_Glyph.
bitmap_top: this field gives the distance in integer pixels from
the current pen position (located on the baseline) to
the top-most pixel of the glyph image WHEN IT IS A
BITMAP. Positive values correspond to upwards Y.
loader: this is a new private field for the glyph slot. Client
applications should not touch it..
- support for transforms and direct rendering in FT_Load_Glyph:
Most of the functionality found in <freetype/ftglyph.h> has been
moved to the core library. Hence, the following:
- a transform can be specified for a face through FT_Set_Transform.
this transform is applied by FT_Load_Glyph to scalable glyph images
(i.e. NOT TO BITMAPS) before the function returns, unless the
bit flag FT_LOAD_IGNORE_TRANSFORM was set in the load flags..
- once a glyph image has been loaded, it can be directly converted to
a bitmap by using the new FT_Render_Glyph function. Note that this
function takes the glyph image from the glyph slot, and converts
it to a bitmap whose properties are returned in "face.glyph.bitmap",
"face.glyph.bitmap_left" and "face.glyph.bitmap_top". The original
native image might be lost after the conversion.
- when using the new bit flag FT_LOAD_RENDER, the FT_Load_Glyph
and FT_Load_Char functions will call FT_Render_Glyph automatically
when needed.
2000-06-22 02:17:42 +02:00
|
|
|
FT_Vector* cur = builder->current->points + first;
|
2000-06-16 21:34:52 +02:00
|
|
|
FT_Vector* limit = cur + last - first + 1;
|
1999-12-17 00:11:37 +01:00
|
|
|
|
2000-06-25 08:47:11 +02:00
|
|
|
|
1999-12-17 00:11:37 +01:00
|
|
|
/* first of all, sort the active stem hints */
|
|
|
|
t1_sort_hints( hori_stems );
|
|
|
|
t1_sort_hints( vert_stems );
|
|
|
|
|
|
|
|
for ( ; cur < limit; cur++ )
|
|
|
|
{
|
|
|
|
cur->x = t1_hint_point( vert_stems, cur->x, scale_x );
|
|
|
|
cur->y = t1_hint_point( hori_stems, cur->y, scale_y );
|
|
|
|
}
|
|
|
|
|
- MAJOR INTERNAL REDESIGN:
A lot of internal modifications have been performed lately on the
source in order to provide the following enhancements:
- more generic module support:
The FT_Module type is now defined to represent a handle to a given
module. The file <freetype/ftmodule.h> contains the FT_Module_Class
definition, as well as the module-loading public API
The FT_Driver type is still defined, and still represents a pointer
to a font driver. Note that FT_Add_Driver is replaced by FT_Add_Module,
FT_Get_Driver by FT_Get_Module, etc..
- support for generic glyph image types:
The FT_Renderer type is a pointer to a module used to perform various
operations on glyph image.
Each renderer is capable of handling images in a single format
(e.g. ft_glyph_format_outline). Its functions are used to:
- transform an glyph image
- render a glyph image into a bitmap
- return the control box (dimensions) of a given glyph image
The scan converters "ftraster.c" and "ftgrays.c" have been moved
to the new directory "src/renderer", and are used to provide two
default renderer modules.
One corresponds to the "standard" scan-converter, the other to the
"smooth" one.
The current renderer can be set through the new function
FT_Set_Renderer.
The old raster-related function FT_Set_Raster, FT_Get_Raster and
FT_Set_Raster_Mode have now disappeared, in favor of the new:
FT_Get_Renderer
FT_Set_Renderer
see the file <freetype/ftrender.h> for more details..
These changes were necessary to properly support different scalable
formats in the future, like bi-color glyphs, etc..
- glyph loader object:
A new internal object, called a 'glyph loader' has been introduced
in the base layer. It is used by all scalable format font drivers
to load glyphs and composites.
This object has been created to reduce the code size of each driver,
as each one of them basically re-implemented its functionality.
See <freetype/internal/ftobjs.h> and the FT_GlyphLoader type for
more information..
- FT_GlyphSlot had new fields:
In order to support extended features (see below), the FT_GlyphSlot
structure has a few new fields:
linearHoriAdvance: this field gives the linearly scaled (i.e.
scaled but unhinted) advance width for the glyph,
expressed as a 16.16 fixed pixel value. This
is useful to perform WYSIWYG text.
linearVertAdvance: this field gives the linearly scaled advance
height for the glyph (relevant in vertical glyph
layouts only). This is useful to perform
WYSIWYG text.
Note that the two above field replace the removed "metrics2" field
in the glyph slot.
advance: this field is a vector that gives the transformed
advance for the glyph. By default, it corresponds
to the advance width, unless FT_LOAD_VERTICAL_LAYOUT
was specified when calling FT_Load_Glyph or FT_Load_Char
bitmap_left: this field gives the distance in integer pixels from
the current pen position to the left-most pixel of
a glyph image WHEN IT IS A BITMAP. It is only valid
when the "format" field is set to
"ft_glyph_format_bitmap", for example, after calling
the new function FT_Render_Glyph.
bitmap_top: this field gives the distance in integer pixels from
the current pen position (located on the baseline) to
the top-most pixel of the glyph image WHEN IT IS A
BITMAP. Positive values correspond to upwards Y.
loader: this is a new private field for the glyph slot. Client
applications should not touch it..
- support for transforms and direct rendering in FT_Load_Glyph:
Most of the functionality found in <freetype/ftglyph.h> has been
moved to the core library. Hence, the following:
- a transform can be specified for a face through FT_Set_Transform.
this transform is applied by FT_Load_Glyph to scalable glyph images
(i.e. NOT TO BITMAPS) before the function returns, unless the
bit flag FT_LOAD_IGNORE_TRANSFORM was set in the load flags..
- once a glyph image has been loaded, it can be directly converted to
a bitmap by using the new FT_Render_Glyph function. Note that this
function takes the glyph image from the glyph slot, and converts
it to a bitmap whose properties are returned in "face.glyph.bitmap",
"face.glyph.bitmap_left" and "face.glyph.bitmap_top". The original
native image might be lost after the conversion.
- when using the new bit flag FT_LOAD_RENDER, the FT_Load_Glyph
and FT_Load_Char functions will call FT_Render_Glyph automatically
when needed.
2000-06-22 02:17:42 +02:00
|
|
|
builder->hint_point = builder->current->n_points;
|
1999-12-17 00:11:37 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2000-06-25 08:47:11 +02:00
|
|
|
/*************************************************************************/
|
|
|
|
/* */
|
|
|
|
/* <Function> */
|
|
|
|
/* T1_Hint_Stems */
|
|
|
|
/* */
|
|
|
|
/* <Description> */
|
|
|
|
/* This function is used to compute the location of each stem hint */
|
|
|
|
/* between the first and second passes of the glyph loader on the */
|
|
|
|
/* charstring. */
|
|
|
|
/* */
|
|
|
|
/* <Input> */
|
|
|
|
/* builder :: A handle to the target builder. */
|
|
|
|
/* */
|
1999-12-17 00:11:37 +01:00
|
|
|
LOCAL_FUNC
|
|
|
|
void T1_Hint_Stems( T1_Builder* builder )
|
|
|
|
{
|
|
|
|
T1_Glyph_Hints* hints = builder->glyph->hints;
|
2000-05-02 12:59:01 +02:00
|
|
|
T1_Private* priv = &builder->face->type1.private_dict;
|
1999-12-17 00:11:37 +01:00
|
|
|
|
|
|
|
T1_Size size = builder->size;
|
2000-06-16 21:34:52 +02:00
|
|
|
FT_Fixed scale_x = size->root.metrics.x_scale;
|
|
|
|
FT_Fixed scale_y = size->root.metrics.y_scale;
|
1999-12-17 00:11:37 +01:00
|
|
|
|
2000-06-25 08:47:11 +02:00
|
|
|
|
1999-12-17 00:11:37 +01:00
|
|
|
t1_hint_horizontal_stems( &hints->hori_stems,
|
|
|
|
builder->size->hints,
|
|
|
|
priv->blue_shift,
|
|
|
|
scale_y );
|
|
|
|
|
|
|
|
t1_hint_vertical_stems( &hints->vert_stems,
|
|
|
|
builder->size->hints,
|
|
|
|
scale_x );
|
|
|
|
}
|
|
|
|
|
2000-06-25 08:47:11 +02:00
|
|
|
|
|
|
|
/* END */
|