ReactOS 0.4.16-dev-340-g0540c21
ttgload.c File Reference
#include <ft2build.h>
#include "ttgload.h"
#include "ttpload.h"
#include "tterrors.h"
#include "ttsubpix.h"
Include dependency graph for ttgload.c:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Macros

#define FT_COMPONENT   trace_ttgload
 
#define ARGS_ARE_WORDS   0x0001
 
#define ARGS_ARE_XY_VALUES   0x0002
 
#define ROUND_XY_TO_GRID   0x0004
 
#define WE_HAVE_A_SCALE   0x0008
 
#define MORE_COMPONENTS   0x0020
 
#define WE_HAVE_AN_XY_SCALE   0x0040
 
#define WE_HAVE_A_2X2   0x0080
 
#define WE_HAVE_INSTR   0x0100
 
#define USE_MY_METRICS   0x0200
 
#define OVERLAP_COMPOUND   0x0400
 
#define SCALED_COMPONENT_OFFSET   0x0800
 
#define UNSCALED_COMPONENT_OFFSET   0x1000
 
#define IS_DEFAULT_INSTANCE   1
 

Functions

 TT_Get_HMetrics (TT_Face face, FT_UInt idx, FT_Short *lsb, FT_UShort *aw)
 
 TT_Get_VMetrics (TT_Face face, FT_UInt idx, FT_Pos yMax, FT_Short *tsb, FT_UShort *ah)
 
static FT_Error tt_get_metrics (TT_Loader loader, FT_UInt glyph_index)
 
 TT_Access_Glyph_Frame (TT_Loader loader, FT_UInt glyph_index, FT_ULong offset, FT_UInt byte_count)
 
 TT_Forget_Glyph_Frame (TT_Loader loader)
 
 TT_Load_Glyph_Header (TT_Loader loader)
 
 TT_Load_Simple_Glyph (TT_Loader load)
 
 TT_Load_Composite_Glyph (TT_Loader loader)
 
 TT_Init_Glyph_Loading (TT_Face face)
 
static void tt_prepare_zone (TT_GlyphZone zone, FT_GlyphLoad load, FT_UInt start_point, FT_UInt start_contour)
 
static FT_Error TT_Hint_Glyph (TT_Loader loader, FT_Bool is_composite)
 
static FT_Error TT_Process_Simple_Glyph (TT_Loader loader)
 
static FT_Error TT_Process_Composite_Component (TT_Loader loader, FT_SubGlyph subglyph, FT_UInt start_point, FT_UInt num_base_points)
 
static FT_Error TT_Process_Composite_Glyph (TT_Loader loader, FT_UInt start_point, FT_UInt start_contour)
 
static void tt_loader_set_pp (TT_Loader loader)
 
static FT_ListNode ft_list_get_node_at (FT_List list, FT_UInt idx)
 
static FT_Error load_truetype_glyph (TT_Loader loader, FT_UInt glyph_index, FT_UInt recurse_count, FT_Bool header_only)
 
static FT_Error compute_glyph_metrics (TT_Loader loader, FT_UInt glyph_index)
 
static FT_Error tt_loader_init (TT_Loader loader, TT_Size size, TT_GlyphSlot glyph, FT_Int32 load_flags, FT_Bool glyf_table_only)
 
static void tt_loader_done (TT_Loader loader)
 
 TT_Load_Glyph (TT_Size size, TT_GlyphSlot glyph, FT_UInt glyph_index, FT_Int32 load_flags)
 

Macro Definition Documentation

◆ ARGS_ARE_WORDS

#define ARGS_ARE_WORDS   0x0001

Definition at line 55 of file ttgload.c.

◆ ARGS_ARE_XY_VALUES

#define ARGS_ARE_XY_VALUES   0x0002

Definition at line 56 of file ttgload.c.

◆ FT_COMPONENT

#define FT_COMPONENT   trace_ttgload

Definition at line 48 of file ttgload.c.

◆ IS_DEFAULT_INSTANCE

#define IS_DEFAULT_INSTANCE   1

◆ MORE_COMPONENTS

#define MORE_COMPONENTS   0x0020

Definition at line 60 of file ttgload.c.

◆ OVERLAP_COMPOUND

#define OVERLAP_COMPOUND   0x0400

Definition at line 65 of file ttgload.c.

◆ ROUND_XY_TO_GRID

#define ROUND_XY_TO_GRID   0x0004

Definition at line 57 of file ttgload.c.

◆ SCALED_COMPONENT_OFFSET

#define SCALED_COMPONENT_OFFSET   0x0800

Definition at line 66 of file ttgload.c.

◆ UNSCALED_COMPONENT_OFFSET

#define UNSCALED_COMPONENT_OFFSET   0x1000

Definition at line 67 of file ttgload.c.

◆ USE_MY_METRICS

#define USE_MY_METRICS   0x0200

Definition at line 64 of file ttgload.c.

◆ WE_HAVE_A_2X2

#define WE_HAVE_A_2X2   0x0080

Definition at line 62 of file ttgload.c.

◆ WE_HAVE_A_SCALE

#define WE_HAVE_A_SCALE   0x0008

Definition at line 58 of file ttgload.c.

◆ WE_HAVE_AN_XY_SCALE

#define WE_HAVE_AN_XY_SCALE   0x0040

Definition at line 61 of file ttgload.c.

◆ WE_HAVE_INSTR

#define WE_HAVE_INSTR   0x0100

Definition at line 63 of file ttgload.c.

Function Documentation

◆ compute_glyph_metrics()

static FT_Error compute_glyph_metrics ( TT_Loader  loader,
FT_UInt  glyph_index 
)
static

Definition at line 2105 of file ttgload.c.

2107 {
2108 TT_Face face = loader->face;
2109#if defined TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY || \
2110 defined TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
2112#endif
2113
2114 FT_BBox bbox;
2115 FT_Fixed y_scale;
2116 TT_GlyphSlot glyph = loader->glyph;
2117 TT_Size size = loader->size;
2118
2119
2120 y_scale = 0x10000L;
2121 if ( ( loader->load_flags & FT_LOAD_NO_SCALE ) == 0 )
2122 y_scale = size->metrics->y_scale;
2123
2124 if ( glyph->format != FT_GLYPH_FORMAT_COMPOSITE )
2125 FT_Outline_Get_CBox( &glyph->outline, &bbox );
2126 else
2127 bbox = loader->bbox;
2128
2129 /* get the device-independent horizontal advance; it is scaled later */
2130 /* by the base layer. */
2131 glyph->linearHoriAdvance = loader->linear;
2132
2133 glyph->metrics.horiBearingX = bbox.xMin;
2134 glyph->metrics.horiBearingY = bbox.yMax;
2135 glyph->metrics.horiAdvance = loader->pp2.x - loader->pp1.x;
2136
2137 /* Adjust advance width to the value contained in the hdmx table */
2138 /* unless FT_LOAD_COMPUTE_METRICS is set or backward compatibility */
2139 /* mode of the v40 interpreter is active. See `ttinterp.h' for */
2140 /* details on backward compatibility mode. */
2141 if (
2143 !( driver->interpreter_version == TT_INTERPRETER_VERSION_40 &&
2144 ( loader->exec && loader->exec->backward_compatibility ) ) &&
2145#endif
2146 !face->postscript.isFixedPitch &&
2147 IS_HINTED( loader->load_flags ) &&
2148 !( loader->load_flags & FT_LOAD_COMPUTE_METRICS ) )
2149 {
2150 FT_Byte* widthp;
2151
2152
2154 size->metrics->x_ppem,
2155 glyph_index );
2156
2157#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
2158
2159 if ( driver->interpreter_version == TT_INTERPRETER_VERSION_38 )
2160 {
2161 FT_Bool ignore_x_mode;
2162
2163
2164 ignore_x_mode = FT_BOOL( FT_LOAD_TARGET_MODE( loader->load_flags ) !=
2166
2167 if ( widthp &&
2168 ( ( ignore_x_mode && loader->exec->compatible_widths ) ||
2169 !ignore_x_mode ||
2170 SPH_OPTION_BITMAP_WIDTHS ) )
2171 glyph->metrics.horiAdvance = *widthp * 64;
2172 }
2173 else
2174
2175#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
2176
2177 {
2178 if ( widthp )
2179 glyph->metrics.horiAdvance = *widthp * 64;
2180 }
2181 }
2182
2183 /* set glyph dimensions */
2184 glyph->metrics.width = SUB_LONG( bbox.xMax, bbox.xMin );
2185 glyph->metrics.height = SUB_LONG( bbox.yMax, bbox.yMin );
2186
2187 /* Now take care of vertical metrics. In the case where there is */
2188 /* no vertical information within the font (relatively common), */
2189 /* create some metrics manually */
2190 {
2191 FT_Pos top; /* scaled vertical top side bearing */
2192 FT_Pos advance; /* scaled vertical advance height */
2193
2194
2195 /* Get the unscaled top bearing and advance height. */
2196 if ( face->vertical_info &&
2197 face->vertical.number_Of_VMetrics > 0 )
2198 {
2199 top = (FT_Short)FT_DivFix( loader->pp3.y - bbox.yMax,
2200 y_scale );
2201
2202 if ( loader->pp3.y <= loader->pp4.y )
2203 advance = 0;
2204 else
2205 advance = (FT_UShort)FT_DivFix( loader->pp3.y - loader->pp4.y,
2206 y_scale );
2207 }
2208 else
2209 {
2210 FT_Pos height;
2211
2212
2213 /* XXX Compute top side bearing and advance height in */
2214 /* Get_VMetrics instead of here. */
2215
2216 /* NOTE: The OS/2 values are the only `portable' ones, */
2217 /* which is why we use them, if there is an OS/2 */
2218 /* table in the font. Otherwise, we use the */
2219 /* values defined in the horizontal header. */
2220
2222 bbox.yMin ),
2223 y_scale );
2224 if ( face->os2.version != 0xFFFFU )
2225 advance = (FT_Pos)( face->os2.sTypoAscender -
2226 face->os2.sTypoDescender );
2227 else
2228 advance = (FT_Pos)( face->horizontal.Ascender -
2229 face->horizontal.Descender );
2230
2231 top = ( advance - height ) / 2;
2232 }
2233
2234#ifdef FT_CONFIG_OPTION_INCREMENTAL
2235 {
2237 FT_Incremental_MetricsRec incr_metrics;
2239
2240
2241 incr = face->root.internal->incremental_interface;
2242
2243 /* If this is an incrementally loaded font see if there are */
2244 /* overriding metrics for this glyph. */
2245 if ( incr && incr->funcs->get_glyph_metrics )
2246 {
2247 incr_metrics.bearing_x = 0;
2248 incr_metrics.bearing_y = top;
2249 incr_metrics.advance = advance;
2250
2251 error = incr->funcs->get_glyph_metrics( incr->object,
2252 glyph_index,
2253 TRUE,
2254 &incr_metrics );
2255 if ( error )
2256 return error;
2257
2258 top = incr_metrics.bearing_y;
2259 advance = incr_metrics.advance;
2260 }
2261 }
2262
2263 /* GWW: Do vertical metrics get loaded incrementally too? */
2264
2265#endif /* FT_CONFIG_OPTION_INCREMENTAL */
2266
2267 glyph->linearVertAdvance = advance;
2268
2269 /* scale the metrics */
2270 if ( !( loader->load_flags & FT_LOAD_NO_SCALE ) )
2271 {
2272 top = FT_MulFix( top, y_scale );
2273 advance = FT_MulFix( advance, y_scale );
2274 }
2275
2276 /* XXX: for now, we have no better algorithm for the lsb, but it */
2277 /* should work fine. */
2278 /* */
2279 glyph->metrics.vertBearingX = glyph->metrics.horiBearingX -
2280 glyph->metrics.horiAdvance / 2;
2281 glyph->metrics.vertBearingY = top;
2282 glyph->metrics.vertAdvance = advance;
2283 }
2284
2285 return 0;
2286 }
_STLP_MOVE_TO_STD_NAMESPACE void _STLP_CALL advance(_InputIterator &__i, _Distance __n)
#define TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
Definition: ftoption.h:887
#define TRUE
Definition: types.h:120
#define FT_LOAD_TARGET_MODE(x)
Definition: freetype.h:3137
#define FT_LOAD_NO_SCALE
Definition: freetype.h:3009
FT_DivFix(FT_Long a, FT_Long b)
Definition: ftcalc.c:608
#define FT_LOAD_COMPUTE_METRICS
Definition: freetype.h:3025
@ FT_RENDER_MODE_MONO
Definition: freetype.h:3236
FT_MulFix(FT_Long a, FT_Long b)
Definition: ftcalc.c:509
FT_BBox bbox
Definition: ftbbox.c:446
#define SUB_LONG(a, b)
Definition: ftcalc.h:422
#define TT_INTERPRETER_VERSION_38
Definition: ftdriver.h:748
#define TT_INTERPRETER_VERSION_40
Definition: ftdriver.h:749
FT_BEGIN_HEADER typedef signed long FT_Pos
Definition: ftimage.h:58
#define FT_FACE_DRIVER(x)
Definition: ftobjs.h:634
FT_Outline_Get_CBox(const FT_Outline *outline, FT_BBox *acbox)
Definition: ftoutln.c:478
FT_BEGIN_HEADER typedef unsigned char FT_Bool
Definition: fttypes.h:108
unsigned char FT_Byte
Definition: fttypes.h:154
signed long FT_Fixed
Definition: fttypes.h:288
int FT_Error
Definition: fttypes.h:300
unsigned short FT_UShort
Definition: fttypes.h:209
signed short FT_Short
Definition: fttypes.h:198
#define FT_BOOL(x)
Definition: fttypes.h:578
GLint GLint GLsizei GLsizei height
Definition: gl.h:1546
GLsizeiptr size
Definition: glext.h:5919
GLdouble GLdouble GLdouble GLdouble top
Definition: glext.h:10859
GLenum GLuint GLint GLenum face
Definition: glext.h:7025
if(dx< 0)
Definition: linetemp.h:194
#define error(str)
Definition: mkdosfs.c:1605
struct @1679::@1680 driver
FT_Pos xMin
Definition: ftimage.h:117
FT_Pos yMax
Definition: ftimage.h:118
FT_Pos yMin
Definition: ftimage.h:117
FT_Pos xMax
Definition: ftimage.h:118
FT_Outline outline
Definition: freetype.h:1927
FT_Fixed linearHoriAdvance
Definition: freetype.h:1917
FT_Fixed linearVertAdvance
Definition: freetype.h:1918
FT_Glyph_Metrics metrics
Definition: freetype.h:1916
FT_Glyph_Format format
Definition: freetype.h:1921
FT_Incremental_GetGlyphMetricsFunc get_glyph_metrics
Definition: ftincrem.h:274
const FT_Incremental_FuncsRec * funcs
Definition: ftincrem.h:317
FT_Fixed y_scale
Definition: freetype.h:1644
FT_Pos x
Definition: ftimage.h:76
FT_Pos y
Definition: ftimage.h:77
FT_Vector pp4
Definition: tttypes.h:1672
FT_ULong load_flags
Definition: tttypes.h:1642
TT_ExecContext exec
Definition: tttypes.h:1661
TT_Size size
Definition: tttypes.h:1638
FT_Vector pp3
Definition: tttypes.h:1671
FT_GlyphSlot glyph
Definition: tttypes.h:1639
FT_Vector pp2
Definition: tttypes.h:1655
FT_Vector pp1
Definition: tttypes.h:1654
TT_Face face
Definition: tttypes.h:1637
FT_BBox bbox
Definition: tttypes.h:1649
FT_Int linear
Definition: tttypes.h:1652
FT_Size_Metrics * metrics
Definition: ttobjs.h:281
#define IS_HINTED(flags)
Definition: ttobjs.h:417
typedefFT_BEGIN_HEADER struct TT_DriverRec_ * TT_Driver
Definition: ttobjs.h:39
tt_face_get_device_metrics(TT_Face face, FT_UInt ppem, FT_UInt gindex)
Definition: ttpload.c:619

Referenced by TT_Load_Glyph().

◆ ft_list_get_node_at()

static FT_ListNode ft_list_get_node_at ( FT_List  list,
FT_UInt  idx 
)
static

Definition at line 1479 of file ttgload.c.

1481 {
1483
1484
1485 if ( !list )
1486 return NULL;
1487
1488 for ( cur = list->head; cur; cur = cur->next )
1489 {
1490 if ( !idx )
1491 return cur;
1492
1493 idx--;
1494 }
1495
1496 return NULL;
1497 }
Definition: list.h:37
#define NULL
Definition: types.h:112
unsigned int idx
Definition: utils.c:41
FxCollectionEntry * cur

Referenced by load_truetype_glyph().

◆ load_truetype_glyph()

static FT_Error load_truetype_glyph ( TT_Loader  loader,
FT_UInt  glyph_index,
FT_UInt  recurse_count,
FT_Bool  header_only 
)
static

Definition at line 1510 of file ttgload.c.

1514 {
1516 FT_Fixed x_scale, y_scale;
1518 TT_Face face = loader->face;
1519 FT_GlyphLoader gloader = loader->gloader;
1520 FT_Bool opened_frame = 0;
1521
1522#ifdef FT_CONFIG_OPTION_INCREMENTAL
1523 FT_StreamRec inc_stream;
1524 FT_Data glyph_data;
1525 FT_Bool glyph_data_loaded = 0;
1526#endif
1527
1528
1529#ifdef FT_DEBUG_LEVEL_TRACE
1530 if ( recurse_count )
1531 FT_TRACE5(( " nesting level: %d\n", recurse_count ));
1532#endif
1533
1534 /* some fonts have an incorrect value of `maxComponentDepth' */
1535 if ( recurse_count > face->max_profile.maxComponentDepth )
1536 {
1537 FT_TRACE1(( "load_truetype_glyph: maxComponentDepth set to %d\n",
1538 recurse_count ));
1539 face->max_profile.maxComponentDepth = (FT_UShort)recurse_count;
1540 }
1541
1542#ifndef FT_CONFIG_OPTION_INCREMENTAL
1543 /* check glyph index */
1544 if ( glyph_index >= (FT_UInt)face->root.num_glyphs )
1545 {
1546 error = FT_THROW( Invalid_Glyph_Index );
1547 goto Exit;
1548 }
1549#endif
1550
1551 loader->glyph_index = glyph_index;
1552
1553 if ( ( loader->load_flags & FT_LOAD_NO_SCALE ) == 0 )
1554 {
1555 x_scale = loader->size->metrics->x_scale;
1556 y_scale = loader->size->metrics->y_scale;
1557 }
1558 else
1559 {
1560 x_scale = 0x10000L;
1561 y_scale = 0x10000L;
1562 }
1563
1564 /* Set `offset' to the start of the glyph relative to the start of */
1565 /* the `glyf' table, and `byte_len' to the length of the glyph in */
1566 /* bytes. */
1567
1568#ifdef FT_CONFIG_OPTION_INCREMENTAL
1569
1570 /* If we are loading glyph data via the incremental interface, set */
1571 /* the loader stream to a memory stream reading the data returned */
1572 /* by the interface. */
1573 if ( face->root.internal->incremental_interface )
1574 {
1575 error = face->root.internal->incremental_interface->funcs->get_glyph_data(
1576 face->root.internal->incremental_interface->object,
1577 glyph_index, &glyph_data );
1578 if ( error )
1579 goto Exit;
1580
1581 glyph_data_loaded = 1;
1582 offset = 0;
1583 loader->byte_len = glyph_data.length;
1584
1585 FT_ZERO( &inc_stream );
1586 FT_Stream_OpenMemory( &inc_stream,
1587 glyph_data.pointer,
1588 (FT_ULong)glyph_data.length );
1589
1590 loader->stream = &inc_stream;
1591 }
1592 else
1593
1594#endif /* FT_CONFIG_OPTION_INCREMENTAL */
1595
1596 offset = tt_face_get_location( face, glyph_index,
1597 (FT_UInt*)&loader->byte_len );
1598
1599 if ( loader->byte_len > 0 )
1600 {
1601#ifdef FT_CONFIG_OPTION_INCREMENTAL
1602 /* for the incremental interface, `glyf_offset' is always zero */
1603 if ( !face->glyf_offset &&
1604 !face->root.internal->incremental_interface )
1605#else
1606 if ( !face->glyf_offset )
1607#endif /* FT_CONFIG_OPTION_INCREMENTAL */
1608 {
1609 FT_TRACE2(( "no `glyf' table but non-zero `loca' entry\n" ));
1610 error = FT_THROW( Invalid_Table );
1611 goto Exit;
1612 }
1613
1614 error = face->access_glyph_frame( loader, glyph_index,
1615 face->glyf_offset + offset,
1616 (FT_UInt)loader->byte_len );
1617 if ( error )
1618 goto Exit;
1619
1620 opened_frame = 1;
1621
1622 /* read glyph header first */
1623 error = face->read_glyph_header( loader );
1624 if ( error )
1625 goto Exit;
1626
1627 /* the metrics must be computed after loading the glyph header */
1628 /* since we need the glyph's `yMax' value in case the vertical */
1629 /* metrics must be emulated */
1630 error = tt_get_metrics( loader, glyph_index );
1631 if ( error )
1632 goto Exit;
1633
1634 if ( header_only )
1635 goto Exit;
1636 }
1637
1638 if ( loader->byte_len == 0 || loader->n_contours == 0 )
1639 {
1640 loader->bbox.xMin = 0;
1641 loader->bbox.xMax = 0;
1642 loader->bbox.yMin = 0;
1643 loader->bbox.yMax = 0;
1644
1645 error = tt_get_metrics( loader, glyph_index );
1646 if ( error )
1647 goto Exit;
1648
1649 if ( header_only )
1650 goto Exit;
1651
1652 /* must initialize points before (possibly) overriding */
1653 /* glyph metrics from the incremental interface */
1654 tt_loader_set_pp( loader );
1655
1656#ifdef FT_CONFIG_OPTION_INCREMENTAL
1657 tt_get_metrics_incr_overrides( loader, glyph_index );
1658#endif
1659
1660#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
1661
1662 if ( FT_IS_NAMED_INSTANCE( FT_FACE( face ) ) ||
1664 {
1665 /* a small outline structure with four elements for */
1666 /* communication with `TT_Vary_Apply_Glyph_Deltas' */
1667 FT_Vector points[4];
1668 char tags[4] = { 1, 1, 1, 1 };
1669 short contours[4] = { 0, 1, 2, 3 };
1671
1672
1673 points[0].x = loader->pp1.x;
1674 points[0].y = loader->pp1.y;
1675 points[1].x = loader->pp2.x;
1676 points[1].y = loader->pp2.y;
1677
1678 points[2].x = loader->pp3.x;
1679 points[2].y = loader->pp3.y;
1680 points[3].x = loader->pp4.x;
1681 points[3].y = loader->pp4.y;
1682
1683 outline.n_points = 4;
1684 outline.n_contours = 4;
1685 outline.points = points;
1686 outline.tags = tags;
1687 outline.contours = contours;
1688
1689 /* this must be done before scaling */
1690 error = TT_Vary_Apply_Glyph_Deltas( loader->face,
1691 glyph_index,
1692 &outline,
1693 (FT_UInt)outline.n_points );
1694 if ( error )
1695 goto Exit;
1696
1697 loader->pp1.x = points[0].x;
1698 loader->pp1.y = points[0].y;
1699 loader->pp2.x = points[1].x;
1700 loader->pp2.y = points[1].y;
1701
1702 loader->pp3.x = points[2].x;
1703 loader->pp3.y = points[2].y;
1704 loader->pp4.x = points[3].x;
1705 loader->pp4.y = points[3].y;
1706
1707
1708 /* recalculate linear horizontal and vertical advances */
1709 /* if we don't have HVAR and VVAR, respectively */
1710 if ( !( loader->face->variation_support & TT_FACE_FLAG_VAR_HADVANCE ) )
1711 loader->linear = loader->pp2.x - loader->pp1.x;
1712 if ( !( loader->face->variation_support & TT_FACE_FLAG_VAR_VADVANCE ) )
1713 loader->vadvance = loader->pp4.x - loader->pp3.x;
1714 }
1715
1716#endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */
1717
1718 /* scale phantom points, if necessary; */
1719 /* they get rounded in `TT_Hint_Glyph' */
1720 if ( ( loader->load_flags & FT_LOAD_NO_SCALE ) == 0 )
1721 {
1722 loader->pp1.x = FT_MulFix( loader->pp1.x, x_scale );
1723 loader->pp2.x = FT_MulFix( loader->pp2.x, x_scale );
1724 /* pp1.y and pp2.y are always zero */
1725
1726 loader->pp3.x = FT_MulFix( loader->pp3.x, x_scale );
1727 loader->pp3.y = FT_MulFix( loader->pp3.y, y_scale );
1728 loader->pp4.x = FT_MulFix( loader->pp4.x, x_scale );
1729 loader->pp4.y = FT_MulFix( loader->pp4.y, y_scale );
1730 }
1731
1732 error = FT_Err_Ok;
1733 goto Exit;
1734 }
1735
1736 /* must initialize phantom points before (possibly) overriding */
1737 /* glyph metrics from the incremental interface */
1738 tt_loader_set_pp( loader );
1739
1740#ifdef FT_CONFIG_OPTION_INCREMENTAL
1741 tt_get_metrics_incr_overrides( loader, glyph_index );
1742#endif
1743
1744 /***********************************************************************/
1745 /***********************************************************************/
1746 /***********************************************************************/
1747
1748 /* if it is a simple glyph, load it */
1749
1750 if ( loader->n_contours > 0 )
1751 {
1752 error = face->read_simple_glyph( loader );
1753 if ( error )
1754 goto Exit;
1755
1756 /* all data have been read */
1757 face->forget_glyph_frame( loader );
1758 opened_frame = 0;
1759
1760 error = TT_Process_Simple_Glyph( loader );
1761 if ( error )
1762 goto Exit;
1763
1764 FT_GlyphLoader_Add( gloader );
1765 }
1766
1767 /***********************************************************************/
1768 /***********************************************************************/
1769 /***********************************************************************/
1770
1771 /* otherwise, load a composite! */
1772 else if ( loader->n_contours < 0 )
1773 {
1774 FT_Memory memory = face->root.memory;
1775
1776 FT_UInt start_point;
1777 FT_UInt start_contour;
1778 FT_ULong ins_pos; /* position of composite instructions, if any */
1779
1780 FT_ListNode node, node2;
1781
1782
1783 /* normalize the `n_contours' value */
1784 loader->n_contours = -1;
1785
1786 /*
1787 * We store the glyph index directly in the `node->data' pointer,
1788 * following the glib solution (cf. macro `GUINT_TO_POINTER') with a
1789 * double cast to make this portable. Note, however, that this needs
1790 * pointers with a width of at least 32 bits.
1791 */
1792
1793
1794 /* clear the nodes filled by sibling chains */
1795 node = ft_list_get_node_at( &loader->composites, recurse_count );
1796 for ( node2 = node; node2; node2 = node2->next )
1797 node2->data = (void*)FT_ULONG_MAX;
1798
1799 /* check whether we already have a composite glyph with this index */
1800 if ( FT_List_Find( &loader->composites,
1801 FT_UINT_TO_POINTER( glyph_index ) ) )
1802 {
1803 FT_TRACE1(( "TT_Load_Composite_Glyph:"
1804 " infinite recursion detected\n" ));
1805 error = FT_THROW( Invalid_Composite );
1806 goto Exit;
1807 }
1808
1809 else if ( node )
1810 node->data = FT_UINT_TO_POINTER( glyph_index );
1811
1812 else
1813 {
1814 if ( FT_NEW( node ) )
1815 goto Exit;
1816 node->data = FT_UINT_TO_POINTER( glyph_index );
1817 FT_List_Add( &loader->composites, node );
1818 }
1819
1820 start_point = (FT_UInt)gloader->base.outline.n_points;
1821 start_contour = (FT_UInt)gloader->base.outline.n_contours;
1822
1823 /* for each subglyph, read composite header */
1824 error = face->read_composite_glyph( loader );
1825 if ( error )
1826 goto Exit;
1827
1828 /* store the offset of instructions */
1829 ins_pos = loader->ins_pos;
1830
1831 /* all data we need are read */
1832 face->forget_glyph_frame( loader );
1833 opened_frame = 0;
1834
1835#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
1836
1837 if ( FT_IS_NAMED_INSTANCE( FT_FACE( face ) ) ||
1839 {
1840 short i, limit;
1841 FT_SubGlyph subglyph;
1842
1845 char* tags = NULL;
1846 short* contours = NULL;
1847
1848
1849 limit = (short)gloader->current.num_subglyphs;
1850
1851 /* construct an outline structure for */
1852 /* communication with `TT_Vary_Apply_Glyph_Deltas' */
1853 outline.n_points = (short)( gloader->current.num_subglyphs + 4 );
1854 outline.n_contours = outline.n_points;
1855
1856 outline.points = NULL;
1857 outline.tags = NULL;
1858 outline.contours = NULL;
1859
1860 if ( FT_NEW_ARRAY( points, outline.n_points ) ||
1861 FT_NEW_ARRAY( tags, outline.n_points ) ||
1862 FT_NEW_ARRAY( contours, outline.n_points ) )
1863 goto Exit1;
1864
1865 subglyph = gloader->current.subglyphs;
1866
1867 for ( i = 0; i < limit; i++, subglyph++ )
1868 {
1869 /* applying deltas for anchor points doesn't make sense, */
1870 /* but we don't have to specially check this since */
1871 /* unused delta values are zero anyways */
1872 points[i].x = subglyph->arg1;
1873 points[i].y = subglyph->arg2;
1874 tags[i] = 1;
1875 contours[i] = i;
1876 }
1877
1878 points[i].x = loader->pp1.x;
1879 points[i].y = loader->pp1.y;
1880 tags[i] = 1;
1881 contours[i] = i;
1882
1883 i++;
1884 points[i].x = loader->pp2.x;
1885 points[i].y = loader->pp2.y;
1886 tags[i] = 1;
1887 contours[i] = i;
1888
1889 i++;
1890 points[i].x = loader->pp3.x;
1891 points[i].y = loader->pp3.y;
1892 tags[i] = 1;
1893 contours[i] = i;
1894
1895 i++;
1896 points[i].x = loader->pp4.x;
1897 points[i].y = loader->pp4.y;
1898 tags[i] = 1;
1899 contours[i] = i;
1900
1901 outline.points = points;
1902 outline.tags = tags;
1903 outline.contours = contours;
1904
1905 /* this call provides additional offsets */
1906 /* for each component's translation */
1907 if ( FT_SET_ERROR( TT_Vary_Apply_Glyph_Deltas(
1908 face,
1909 glyph_index,
1910 &outline,
1911 (FT_UInt)outline.n_points ) ) )
1912 goto Exit1;
1913
1914 subglyph = gloader->current.subglyphs;
1915
1916 for ( i = 0; i < limit; i++, subglyph++ )
1917 {
1918 if ( subglyph->flags & ARGS_ARE_XY_VALUES )
1919 {
1920 subglyph->arg1 = (FT_Int16)points[i].x;
1921 subglyph->arg2 = (FT_Int16)points[i].y;
1922 }
1923 }
1924
1925 loader->pp1.x = points[i + 0].x;
1926 loader->pp1.y = points[i + 0].y;
1927 loader->pp2.x = points[i + 1].x;
1928 loader->pp2.y = points[i + 1].y;
1929
1930 loader->pp3.x = points[i + 2].x;
1931 loader->pp3.y = points[i + 2].y;
1932 loader->pp4.x = points[i + 3].x;
1933 loader->pp4.y = points[i + 3].y;
1934
1935 /* recalculate linear horizontal and vertical advances */
1936 /* if we don't have HVAR and VVAR, respectively */
1937 if ( !( face->variation_support & TT_FACE_FLAG_VAR_HADVANCE ) )
1938 loader->linear = loader->pp2.x - loader->pp1.x;
1939 if ( !( face->variation_support & TT_FACE_FLAG_VAR_VADVANCE ) )
1940 loader->vadvance = loader->pp4.x - loader->pp3.x;
1941
1942 Exit1:
1943 FT_FREE( outline.points );
1944 FT_FREE( outline.tags );
1945 FT_FREE( outline.contours );
1946
1947 if ( error )
1948 goto Exit;
1949 }
1950
1951#endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */
1952
1953 /* scale phantom points, if necessary; */
1954 /* they get rounded in `TT_Hint_Glyph' */
1955 if ( ( loader->load_flags & FT_LOAD_NO_SCALE ) == 0 )
1956 {
1957 loader->pp1.x = FT_MulFix( loader->pp1.x, x_scale );
1958 loader->pp2.x = FT_MulFix( loader->pp2.x, x_scale );
1959 /* pp1.y and pp2.y are always zero */
1960
1961 loader->pp3.x = FT_MulFix( loader->pp3.x, x_scale );
1962 loader->pp3.y = FT_MulFix( loader->pp3.y, y_scale );
1963 loader->pp4.x = FT_MulFix( loader->pp4.x, x_scale );
1964 loader->pp4.y = FT_MulFix( loader->pp4.y, y_scale );
1965 }
1966
1967 /* if the flag FT_LOAD_NO_RECURSE is set, we return the subglyph */
1968 /* `as is' in the glyph slot (the client application will be */
1969 /* responsible for interpreting these data)... */
1970 if ( loader->load_flags & FT_LOAD_NO_RECURSE )
1971 {
1972 FT_GlyphLoader_Add( gloader );
1973 loader->glyph->format = FT_GLYPH_FORMAT_COMPOSITE;
1974
1975 goto Exit;
1976 }
1977
1978 /*********************************************************************/
1979 /*********************************************************************/
1980 /*********************************************************************/
1981
1982 {
1983 FT_UInt n, num_base_points;
1984 FT_SubGlyph subglyph = NULL;
1985
1986 FT_UInt num_points = start_point;
1987 FT_UInt num_subglyphs = gloader->current.num_subglyphs;
1988 FT_UInt num_base_subgs = gloader->base.num_subglyphs;
1989
1990 FT_Stream old_stream = loader->stream;
1991 FT_Int old_byte_len = loader->byte_len;
1992
1993
1994 FT_GlyphLoader_Add( gloader );
1995
1996 /* read each subglyph independently */
1997 for ( n = 0; n < num_subglyphs; n++ )
1998 {
1999 FT_Vector pp[4];
2000
2001 FT_Int linear_hadvance;
2002 FT_Int linear_vadvance;
2003
2004
2005 /* Each time we call load_truetype_glyph in this loop, the */
2006 /* value of `gloader.base.subglyphs' can change due to table */
2007 /* reallocations. We thus need to recompute the subglyph */
2008 /* pointer on each iteration. */
2009 subglyph = gloader->base.subglyphs + num_base_subgs + n;
2010
2011 pp[0] = loader->pp1;
2012 pp[1] = loader->pp2;
2013 pp[2] = loader->pp3;
2014 pp[3] = loader->pp4;
2015
2016 linear_hadvance = loader->linear;
2017 linear_vadvance = loader->vadvance;
2018
2019 num_base_points = (FT_UInt)gloader->base.outline.n_points;
2020
2021 error = load_truetype_glyph( loader,
2022 (FT_UInt)subglyph->index,
2023 recurse_count + 1,
2024 FALSE );
2025 if ( error )
2026 goto Exit;
2027
2028 /* restore subglyph pointer */
2029 subglyph = gloader->base.subglyphs + num_base_subgs + n;
2030
2031 /* restore phantom points if necessary */
2032 if ( !( subglyph->flags & USE_MY_METRICS ) )
2033 {
2034 loader->pp1 = pp[0];
2035 loader->pp2 = pp[1];
2036 loader->pp3 = pp[2];
2037 loader->pp4 = pp[3];
2038
2039 loader->linear = linear_hadvance;
2040 loader->vadvance = linear_vadvance;
2041 }
2042
2043 num_points = (FT_UInt)gloader->base.outline.n_points;
2044
2045 if ( num_points == num_base_points )
2046 continue;
2047
2048 /* gloader->base.outline consists of three parts: */
2049 /* 0 -(1)-> start_point -(2)-> num_base_points -(3)-> n_points. */
2050 /* */
2051 /* (1): exists from the beginning */
2052 /* (2): components that have been loaded so far */
2053 /* (3): the newly loaded component */
2055 subglyph,
2056 start_point,
2057 num_base_points );
2058 if ( error )
2059 goto Exit;
2060 }
2061
2062 loader->stream = old_stream;
2063 loader->byte_len = old_byte_len;
2064
2065 /* process the glyph */
2066 loader->ins_pos = ins_pos;
2067 if ( IS_HINTED( loader->load_flags ) &&
2069 subglyph->flags & WE_HAVE_INSTR &&
2070#endif
2071 num_points > start_point )
2072 {
2074 start_point,
2075 start_contour );
2076 if ( error )
2077 goto Exit;
2078 }
2079 }
2080 }
2081
2082 /***********************************************************************/
2083 /***********************************************************************/
2084 /***********************************************************************/
2085
2086 Exit:
2087
2088 if ( opened_frame )
2089 face->forget_glyph_frame( loader );
2090
2091#ifdef FT_CONFIG_OPTION_INCREMENTAL
2092
2093 if ( glyph_data_loaded )
2094 face->root.internal->incremental_interface->funcs->free_glyph_data(
2095 face->root.internal->incremental_interface->object,
2096 &glyph_data );
2097
2098#endif
2099
2100 return error;
2101 }
#define TT_USE_BYTECODE_INTERPRETER
Definition: ftoption.h:879
#define FALSE
Definition: types.h:117
unsigned short(__cdecl typeof(TIFFCurrentDirectory))(struct tiff *)
Definition: typeof.h:94
#define FT_LOAD_NO_RECURSE
Definition: freetype.h:3018
#define FT_IS_VARIATION(face)
Definition: freetype.h:1442
#define FT_IS_NAMED_INSTANCE(face)
Definition: freetype.h:1424
return FT_Err_Ok
Definition: ftbbox.c:511
signed short FT_Int16
Definition: ftconfig.h:170
#define FT_UINT_TO_POINTER(x)
Definition: ftconfig.h:341
#define FT_TRACE5(varformat)
Definition: ftdebug.h:162
#define FT_THROW(e)
Definition: ftdebug.h:213
#define FT_TRACE2(varformat)
Definition: ftdebug.h:159
#define FT_TRACE1(varformat)
Definition: ftdebug.h:158
FT_GlyphLoader_Add(FT_GlyphLoader loader)
Definition: ftgloadr.c:328
FT_BEGIN_HEADER FT_List_Find(FT_List list, void *data)
Definition: ftutil.c:244
FT_List_Add(FT_List list, FT_ListNode node)
Definition: ftutil.c:269
#define FT_NEW_ARRAY(ptr, count)
Definition: ftmemory.h:333
#define FT_NEW(ptr)
Definition: ftmemory.h:331
#define FT_SET_ERROR(expression)
Definition: ftmemory.h:42
#define FT_FREE(ptr)
Definition: ftmemory.h:329
#define FT_ZERO(p)
Definition: ftmemory.h:237
#define FT_FACE(x)
Definition: ftobjs.h:630
#define FT_ULONG_MAX
Definition: ftstdlib.h:68
FT_Stream_OpenMemory(FT_Stream stream, const FT_Byte *base, FT_ULong size)
Definition: ftstream.c:35
typedefFT_BEGIN_HEADER struct FT_MemoryRec_ * FT_Memory
Definition: ftsystem.h:66
unsigned long FT_ULong
Definition: fttypes.h:253
unsigned int FT_UInt
Definition: fttypes.h:231
signed int FT_Int
Definition: fttypes.h:220
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
GLint GLint GLint GLint GLint GLint y
Definition: gl.h:1548
GLdouble n
Definition: glext.h:7729
GLint limit
Definition: glext.h:10326
GLsizei const GLfloat * points
Definition: glext.h:8112
GLintptr offset
Definition: glext.h:5920
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
const char * tags[7 *8]
Definition: apphelp.c:216
static char memory[1024 *256]
Definition: process.c:116
static void Exit(void)
Definition: sock.c:1330
const FT_Byte * pointer
Definition: fttypes.h:408
FT_Int length
Definition: fttypes.h:409
FT_SubGlyph subglyphs
Definition: ftgloadr.h:56
FT_UInt num_subglyphs
Definition: ftgloadr.h:55
FT_Outline outline
Definition: ftgloadr.h:52
FT_GlyphLoadRec current
Definition: ftgloadr.h:70
FT_GlyphLoadRec base
Definition: ftgloadr.h:69
FT_ListNode next
Definition: fttypes.h:547
void * data
Definition: fttypes.h:548
short n_contours
Definition: ftimage.h:336
short n_points
Definition: ftimage.h:337
FT_Fixed x_scale
Definition: freetype.h:1643
FT_Int arg2
Definition: ftgloadr.h:44
FT_UShort flags
Definition: ftgloadr.h:42
FT_Int index
Definition: ftgloadr.h:41
FT_Int arg1
Definition: ftgloadr.h:43
FT_Int byte_len
Definition: tttypes.h:1646
FT_UInt glyph_index
Definition: tttypes.h:1643
FT_ULong ins_pos
Definition: tttypes.h:1663
FT_GlyphLoader gloader
Definition: tttypes.h:1640
FT_ListRec composites
Definition: tttypes.h:1679
FT_Short n_contours
Definition: tttypes.h:1648
FT_Stream stream
Definition: tttypes.h:1645
FT_Int vadvance
Definition: tttypes.h:1670
Definition: mesh.c:5330
#define WE_HAVE_INSTR
Definition: ttgload.c:63
static FT_Error TT_Process_Composite_Glyph(TT_Loader loader, FT_UInt start_point, FT_UInt start_contour)
Definition: ttgload.c:1253
static FT_Error load_truetype_glyph(TT_Loader loader, FT_UInt glyph_index, FT_UInt recurse_count, FT_Bool header_only)
Definition: ttgload.c:1510
static FT_Error tt_get_metrics(TT_Loader loader, FT_UInt glyph_index)
Definition: ttgload.c:122
static void tt_loader_set_pp(TT_Loader loader)
Definition: ttgload.c:1433
#define USE_MY_METRICS
Definition: ttgload.c:64
static FT_Error TT_Process_Simple_Glyph(TT_Loader loader)
Definition: ttgload.c:910
static FT_Error TT_Process_Composite_Component(TT_Loader loader, FT_SubGlyph subglyph, FT_UInt start_point, FT_UInt num_base_points)
Definition: ttgload.c:1084
static FT_ListNode ft_list_get_node_at(FT_List list, FT_UInt idx)
Definition: ttgload.c:1479
#define ARGS_ARE_XY_VALUES
Definition: ttgload.c:56
tt_face_get_location(TT_Face face, FT_UInt gindex, FT_UInt *asize)
Definition: ttpload.c:195
#define TT_FACE_FLAG_VAR_HADVANCE
Definition: tttypes.h:1113
#define TT_FACE_FLAG_VAR_VADVANCE
Definition: tttypes.h:1118
Definition: dlist.c:348
GLvoid * data
Definition: dlist.c:359

Referenced by load_truetype_glyph(), and TT_Load_Glyph().

◆ TT_Access_Glyph_Frame()

TT_Access_Glyph_Frame ( TT_Loader  loader,
FT_UInt  glyph_index,
FT_ULong  offset,
FT_UInt  byte_count 
)

Definition at line 262 of file ttgload.c.

266 {
268 FT_Stream stream = loader->stream;
269
270 /* for non-debug mode */
271 FT_UNUSED( glyph_index );
272
273
274 FT_TRACE4(( "Glyph %ld\n", glyph_index ));
275
276 /* the following line sets the `error' variable through macros! */
277 if ( FT_STREAM_SEEK( offset ) || FT_FRAME_ENTER( byte_count ) )
278 return error;
279
280 loader->cursor = stream->cursor;
281 loader->limit = stream->limit;
282
283 return FT_Err_Ok;
284 }
#define FT_UNUSED(arg)
Definition: ftconfig.h:101
#define FT_TRACE4(varformat)
Definition: ftdebug.h:161
#define FT_FRAME_ENTER(size)
Definition: ftstream.h:512
#define FT_STREAM_SEEK(position)
Definition: ftstream.h:489
FT_Byte * limit
Definition: tttypes.h:1676
FT_Byte * cursor
Definition: tttypes.h:1675
Definition: parse.h:23

Referenced by TT_Init_Glyph_Loading().

◆ TT_Forget_Glyph_Frame()

TT_Forget_Glyph_Frame ( TT_Loader  loader)

Definition at line 288 of file ttgload.c.

289 {
290 FT_Stream stream = loader->stream;
291
292
294 }
#define FT_FRAME_EXIT()
Definition: ftstream.h:517

Referenced by TT_Init_Glyph_Loading().

◆ TT_Get_HMetrics()

TT_Get_HMetrics ( TT_Face  face,
FT_UInt  idx,
FT_Short lsb,
FT_UShort aw 
)

Definition at line 75 of file ttgload.c.

79 {
80 ( (SFNT_Service)face->sfnt )->get_metrics( face, 0, idx, lsb, aw );
81
82 FT_TRACE5(( " advance width (font units): %d\n", *aw ));
83 FT_TRACE5(( " left side bearing (font units): %d\n", *lsb ));
84 }
SFNT_Interface * SFNT_Service
Definition: sfnt.h:628

Referenced by tt_get_metrics(), and TT_Load_Glyph().

◆ tt_get_metrics()

static FT_Error tt_get_metrics ( TT_Loader  loader,
FT_UInt  glyph_index 
)
static

Definition at line 122 of file ttgload.c.

124 {
125 TT_Face face = loader->face;
126#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
128#endif
129
131 FT_Stream stream = loader->stream;
132
133 FT_Short left_bearing = 0, top_bearing = 0;
134 FT_UShort advance_width = 0, advance_height = 0;
135
136 /* we must preserve the stream position */
137 /* (which gets altered by the metrics functions) */
139
140
141 TT_Get_HMetrics( face, glyph_index,
142 &left_bearing,
143 &advance_width );
144 TT_Get_VMetrics( face, glyph_index,
145 loader->bbox.yMax,
146 &top_bearing,
147 &advance_height );
148
149 if ( FT_STREAM_SEEK( pos ) )
150 return error;
151
152 loader->left_bearing = left_bearing;
153 loader->advance = advance_width;
154 loader->top_bearing = top_bearing;
155 loader->vadvance = advance_height;
156
157#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
158 if ( driver->interpreter_version == TT_INTERPRETER_VERSION_38 &&
159 loader->exec )
160 {
161 loader->exec->sph_tweak_flags = 0;
162
163 /* This may not be the right place for this, but it works... */
164 /* Note that we have to unconditionally load the tweaks since */
165 /* it is possible that glyphs individually switch ClearType's */
166 /* backward compatibility mode on and off. */
167 sph_set_tweaks( loader, glyph_index );
168 }
169#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
170
171 if ( !loader->linear_def )
172 {
173 loader->linear_def = 1;
174 loader->linear = advance_width;
175 }
176
177 return FT_Err_Ok;
178 }
#define FT_STREAM_POS()
Definition: ftstream.h:486
FT_Int top_bearing
Definition: tttypes.h:1669
FT_Int advance
Definition: tttypes.h:1651
FT_Bool linear_def
Definition: tttypes.h:1653
FT_Int left_bearing
Definition: tttypes.h:1650
TT_Get_HMetrics(TT_Face face, FT_UInt idx, FT_Short *lsb, FT_UShort *aw)
Definition: ttgload.c:75
TT_Get_VMetrics(TT_Face face, FT_UInt idx, FT_Pos yMax, FT_Short *tsb, FT_UShort *ah)
Definition: ttgload.c:93

Referenced by load_truetype_glyph().

◆ TT_Get_VMetrics()

TT_Get_VMetrics ( TT_Face  face,
FT_UInt  idx,
FT_Pos  yMax,
FT_Short tsb,
FT_UShort ah 
)

Definition at line 93 of file ttgload.c.

98 {
99 if ( face->vertical_info )
100 ( (SFNT_Service)face->sfnt )->get_metrics( face, 1, idx, tsb, ah );
101
102 else if ( face->os2.version != 0xFFFFU )
103 {
104 *tsb = (FT_Short)( face->os2.sTypoAscender - yMax );
105 *ah = (FT_UShort)FT_ABS( face->os2.sTypoAscender -
106 face->os2.sTypoDescender );
107 }
108
109 else
110 {
111 *tsb = (FT_Short)( face->horizontal.Ascender - yMax );
112 *ah = (FT_UShort)FT_ABS( face->horizontal.Ascender -
113 face->horizontal.Descender );
114 }
115
116 FT_TRACE5(( " advance height (font units): %d\n", *ah ));
117 FT_TRACE5(( " top side bearing (font units): %d\n", *tsb ));
118 }
#define FT_ABS(a)
Definition: ftobjs.h:74

Referenced by tt_get_metrics(), and TT_Load_Glyph().

◆ TT_Hint_Glyph()

static FT_Error TT_Hint_Glyph ( TT_Loader  loader,
FT_Bool  is_composite 
)
static

Definition at line 781 of file ttgload.c.

783 {
784#if defined TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY || \
785 defined TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
786 TT_Face face = loader->face;
788#endif
789
790 TT_GlyphZone zone = &loader->zone;
791
792#ifdef TT_USE_BYTECODE_INTERPRETER
793 FT_Long n_ins;
794#else
795 FT_UNUSED( is_composite );
796#endif
797
798
799#ifdef TT_USE_BYTECODE_INTERPRETER
800 if ( loader->glyph->control_len > 0xFFFFL )
801 {
802 FT_TRACE1(( "TT_Hint_Glyph: too long instructions" ));
803 FT_TRACE1(( " (0x%lx byte) is truncated\n",
804 loader->glyph->control_len ));
805 }
806 n_ins = loader->glyph->control_len;
807
808 /* save original point position in org */
809 if ( n_ins > 0 )
810 FT_ARRAY_COPY( zone->org, zone->cur, zone->n_points );
811
812 /* Reset graphics state. */
813 loader->exec->GS = loader->size->GS;
814
815 /* XXX: UNDOCUMENTED! Hinting instructions of a composite glyph */
816 /* completely refer to the (already) hinted subglyphs. */
817 if ( is_composite )
818 {
819 loader->exec->metrics.x_scale = 1 << 16;
820 loader->exec->metrics.y_scale = 1 << 16;
821
822 FT_ARRAY_COPY( zone->orus, zone->cur, zone->n_points );
823 }
824 else
825 {
826 loader->exec->metrics.x_scale = loader->size->metrics->x_scale;
827 loader->exec->metrics.y_scale = loader->size->metrics->y_scale;
828 }
829#endif
830
831 /* round phantom points */
832 zone->cur[zone->n_points - 4].x =
833 FT_PIX_ROUND( zone->cur[zone->n_points - 4].x );
834 zone->cur[zone->n_points - 3].x =
835 FT_PIX_ROUND( zone->cur[zone->n_points - 3].x );
836 zone->cur[zone->n_points - 2].y =
837 FT_PIX_ROUND( zone->cur[zone->n_points - 2].y );
838 zone->cur[zone->n_points - 1].y =
839 FT_PIX_ROUND( zone->cur[zone->n_points - 1].y );
840
841#ifdef TT_USE_BYTECODE_INTERPRETER
842
843 if ( n_ins > 0 )
844 {
846
847 FT_GlyphLoader gloader = loader->gloader;
848 FT_Outline current_outline = gloader->current.outline;
849
850
851 TT_Set_CodeRange( loader->exec, tt_coderange_glyph,
852 loader->exec->glyphIns, n_ins );
853
854 loader->exec->is_composite = is_composite;
855 loader->exec->pts = *zone;
856
857 error = TT_Run_Context( loader->exec );
858 if ( error && loader->exec->pedantic_hinting )
859 return error;
860
861 /* store drop-out mode in bits 5-7; set bit 2 also as a marker */
862 current_outline.tags[0] |=
863 ( loader->exec->GS.scan_type << 5 ) | FT_CURVE_TAG_HAS_SCANMODE;
864 }
865
866#endif
867
868#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
869 /* Save possibly modified glyph phantom points unless in v40 backward */
870 /* compatibility mode, where no movement on the x axis means no reason */
871 /* to change bearings or advance widths. */
872 if ( !( driver->interpreter_version == TT_INTERPRETER_VERSION_40 &&
873 loader->exec->backward_compatibility ) )
874 {
875#endif
876 loader->pp1 = zone->cur[zone->n_points - 4];
877 loader->pp2 = zone->cur[zone->n_points - 3];
878 loader->pp3 = zone->cur[zone->n_points - 2];
879 loader->pp4 = zone->cur[zone->n_points - 1];
880#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
881 }
882#endif
883
884#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
885 if ( driver->interpreter_version == TT_INTERPRETER_VERSION_38 )
886 {
887 if ( loader->exec->sph_tweak_flags & SPH_TWEAK_DEEMBOLDEN )
888 FT_Outline_EmboldenXY( &loader->gloader->current.outline, -24, 0 );
889
890 else if ( loader->exec->sph_tweak_flags & SPH_TWEAK_EMBOLDEN )
891 FT_Outline_EmboldenXY( &loader->gloader->current.outline, 24, 0 );
892 }
893#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
894
895 return FT_Err_Ok;
896 }
#define FT_CURVE_TAG_HAS_SCANMODE
Definition: ftimage.h:457
#define FT_ARRAY_COPY(dest, source, count)
Definition: ftmemory.h:244
#define FT_PIX_ROUND(x)
Definition: ftobjs.h:93
FT_Outline_EmboldenXY(FT_Outline *outline, FT_Pos xstrength, FT_Pos ystrength)
Definition: ftoutln.c:909
signed long FT_Long
Definition: fttypes.h:242
DWORD zone
Definition: sec_mgr.c:1754
char * tags
Definition: ftimage.h:340
TT_GlyphZoneRec pts
Definition: ttinterp.h:170
FT_Bool is_composite
Definition: ttinterp.h:229
FT_Bool pedantic_hinting
Definition: ttinterp.h:230
TT_GraphicsState GS
Definition: ttinterp.h:177
FT_Size_Metrics metrics
Definition: ttinterp.h:174
FT_Byte * glyphIns
Definition: ttinterp.h:193
FT_Int scan_type
Definition: ttobjs.h:92
TT_GlyphZoneRec zone
Definition: tttypes.h:1659
@ tt_coderange_glyph
Definition: ttobjs.h:140

Referenced by TT_Process_Composite_Glyph(), and TT_Process_Simple_Glyph().

◆ TT_Init_Glyph_Loading()

TT_Init_Glyph_Loading ( TT_Face  face)

Definition at line 742 of file ttgload.c.

743 {
744 face->access_glyph_frame = TT_Access_Glyph_Frame;
745 face->read_glyph_header = TT_Load_Glyph_Header;
746 face->read_simple_glyph = TT_Load_Simple_Glyph;
747 face->read_composite_glyph = TT_Load_Composite_Glyph;
748 face->forget_glyph_frame = TT_Forget_Glyph_Frame;
749 }
TT_Access_Glyph_Frame(TT_Loader loader, FT_UInt glyph_index, FT_ULong offset, FT_UInt byte_count)
Definition: ttgload.c:262
TT_Load_Simple_Glyph(TT_Loader load)
Definition: ttgload.c:326
TT_Load_Glyph_Header(TT_Loader loader)
Definition: ttgload.c:298
TT_Forget_Glyph_Frame(TT_Loader loader)
Definition: ttgload.c:288
TT_Load_Composite_Glyph(TT_Loader loader)
Definition: ttgload.c:559

Referenced by tt_face_init().

◆ TT_Load_Composite_Glyph()

TT_Load_Composite_Glyph ( TT_Loader  loader)

Definition at line 559 of file ttgload.c.

560 {
562 FT_Byte* p = loader->cursor;
563 FT_Byte* limit = loader->limit;
564 FT_GlyphLoader gloader = loader->gloader;
565 FT_SubGlyph subglyph;
566 FT_UInt num_subglyphs;
567
568
569 num_subglyphs = 0;
570
571 do
572 {
573 FT_Fixed xx, xy, yy, yx;
575
576
577 /* check that we can load a new subglyph */
578 error = FT_GlyphLoader_CheckSubGlyphs( gloader, num_subglyphs + 1 );
579 if ( error )
580 goto Fail;
581
582 /* check space */
583 if ( p + 4 > limit )
584 goto Invalid_Composite;
585
586 subglyph = gloader->current.subglyphs + num_subglyphs;
587
588 subglyph->arg1 = subglyph->arg2 = 0;
589
590 subglyph->flags = FT_NEXT_USHORT( p );
591 subglyph->index = FT_NEXT_USHORT( p );
592
593 /* check space */
594 count = 2;
595 if ( subglyph->flags & ARGS_ARE_WORDS )
596 count += 2;
597 if ( subglyph->flags & WE_HAVE_A_SCALE )
598 count += 2;
599 else if ( subglyph->flags & WE_HAVE_AN_XY_SCALE )
600 count += 4;
601 else if ( subglyph->flags & WE_HAVE_A_2X2 )
602 count += 8;
603
604 if ( p + count > limit )
605 goto Invalid_Composite;
606
607 /* read arguments */
608 if ( subglyph->flags & ARGS_ARE_XY_VALUES )
609 {
610 if ( subglyph->flags & ARGS_ARE_WORDS )
611 {
612 subglyph->arg1 = FT_NEXT_SHORT( p );
613 subglyph->arg2 = FT_NEXT_SHORT( p );
614 }
615 else
616 {
617 subglyph->arg1 = FT_NEXT_CHAR( p );
618 subglyph->arg2 = FT_NEXT_CHAR( p );
619 }
620 }
621 else
622 {
623 if ( subglyph->flags & ARGS_ARE_WORDS )
624 {
625 subglyph->arg1 = (FT_Int)FT_NEXT_USHORT( p );
626 subglyph->arg2 = (FT_Int)FT_NEXT_USHORT( p );
627 }
628 else
629 {
630 subglyph->arg1 = (FT_Int)FT_NEXT_BYTE( p );
631 subglyph->arg2 = (FT_Int)FT_NEXT_BYTE( p );
632 }
633 }
634
635 /* read transform */
636 xx = yy = 0x10000L;
637 xy = yx = 0;
638
639 if ( subglyph->flags & WE_HAVE_A_SCALE )
640 {
641 xx = (FT_Fixed)FT_NEXT_SHORT( p ) * 4;
642 yy = xx;
643 }
644 else if ( subglyph->flags & WE_HAVE_AN_XY_SCALE )
645 {
646 xx = (FT_Fixed)FT_NEXT_SHORT( p ) * 4;
647 yy = (FT_Fixed)FT_NEXT_SHORT( p ) * 4;
648 }
649 else if ( subglyph->flags & WE_HAVE_A_2X2 )
650 {
651 xx = (FT_Fixed)FT_NEXT_SHORT( p ) * 4;
652 yx = (FT_Fixed)FT_NEXT_SHORT( p ) * 4;
653 xy = (FT_Fixed)FT_NEXT_SHORT( p ) * 4;
654 yy = (FT_Fixed)FT_NEXT_SHORT( p ) * 4;
655 }
656
657 subglyph->transform.xx = xx;
658 subglyph->transform.xy = xy;
659 subglyph->transform.yx = yx;
660 subglyph->transform.yy = yy;
661
662 num_subglyphs++;
663
664 } while ( subglyph->flags & MORE_COMPONENTS );
665
666 gloader->current.num_subglyphs = num_subglyphs;
667 FT_TRACE5(( " %d component%s\n",
668 num_subglyphs,
669 num_subglyphs > 1 ? "s" : "" ));
670
671#ifdef FT_DEBUG_LEVEL_TRACE
672 {
673 FT_UInt i;
674
675
676 subglyph = gloader->current.subglyphs;
677
678 for ( i = 0; i < num_subglyphs; i++ )
679 {
680 if ( num_subglyphs > 1 )
681 FT_TRACE7(( " subglyph %d:\n", i ));
682
683 FT_TRACE7(( " glyph index: %d\n", subglyph->index ));
684
685 if ( subglyph->flags & ARGS_ARE_XY_VALUES )
686 FT_TRACE7(( " offset: x=%d, y=%d\n",
687 subglyph->arg1,
688 subglyph->arg2 ));
689 else
690 FT_TRACE7(( " matching points: base=%d, component=%d\n",
691 subglyph->arg1,
692 subglyph->arg2 ));
693
694 if ( subglyph->flags & WE_HAVE_A_SCALE )
695 FT_TRACE7(( " scaling: %f\n",
696 subglyph->transform.xx / 65536.0 ));
697 else if ( subglyph->flags & WE_HAVE_AN_XY_SCALE )
698 FT_TRACE7(( " scaling: x=%f, y=%f\n",
699 subglyph->transform.xx / 65536.0,
700 subglyph->transform.yy / 65536.0 ));
701 else if ( subglyph->flags & WE_HAVE_A_2X2 )
702 FT_TRACE7(( " scaling: xx=%f, yx=%f\n"
703 " xy=%f, yy=%f\n",
704 subglyph->transform.xx / 65536.0,
705 subglyph->transform.yx / 65536.0,
706 subglyph->transform.xy / 65536.0,
707 subglyph->transform.yy / 65536.0 ));
708
709 subglyph++;
710 }
711 }
712#endif /* FT_DEBUG_LEVEL_TRACE */
713
714#ifdef TT_USE_BYTECODE_INTERPRETER
715
716 {
717 FT_Stream stream = loader->stream;
718
719
720 /* we must undo the FT_FRAME_ENTER in order to point */
721 /* to the composite instructions, if we find some. */
722 /* We will process them later. */
723 /* */
724 loader->ins_pos = (FT_ULong)( FT_STREAM_POS() +
725 p - limit );
726 }
727
728#endif
729
730 loader->cursor = p;
731
732 Fail:
733 return error;
734
735 Invalid_Composite:
736 error = FT_THROW( Invalid_Composite );
737 goto Fail;
738 }
int Fail
Definition: ehthrow.cxx:24
#define FT_TRACE7(varformat)
Definition: ftdebug.h:164
FT_GlyphLoader_CheckSubGlyphs(FT_GlyphLoader loader, FT_UInt n_subs)
Definition: ftgloadr.c:281
#define FT_NEXT_USHORT(buffer)
Definition: ftstream.h:226
#define FT_NEXT_CHAR(buffer)
Definition: ftstream.h:217
#define FT_NEXT_SHORT(buffer)
Definition: ftstream.h:223
#define FT_NEXT_BYTE(buffer)
Definition: ftstream.h:220
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLfloat GLfloat p
Definition: glext.h:8902
int xx
Definition: npserver.c:29
FT_Fixed xx
Definition: fttypes.h:387
FT_Fixed yx
Definition: fttypes.h:388
FT_Fixed yy
Definition: fttypes.h:388
FT_Fixed xy
Definition: fttypes.h:387
FT_Matrix transform
Definition: ftgloadr.h:45
#define WE_HAVE_A_2X2
Definition: ttgload.c:62
#define WE_HAVE_A_SCALE
Definition: ttgload.c:58
#define MORE_COMPONENTS
Definition: ttgload.c:60
#define ARGS_ARE_WORDS
Definition: ttgload.c:55
#define WE_HAVE_AN_XY_SCALE
Definition: ttgload.c:61

Referenced by TT_Init_Glyph_Loading().

◆ TT_Load_Glyph()

TT_Load_Glyph ( TT_Size  size,
TT_GlyphSlot  glyph,
FT_UInt  glyph_index,
FT_Int32  load_flags 
)

Definition at line 2687 of file ttgload.c.

2691 {
2693 TT_LoaderRec loader;
2694
2695#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
2696#define IS_DEFAULT_INSTANCE ( !( FT_IS_NAMED_INSTANCE( glyph->face ) || \
2697 FT_IS_VARIATION( glyph->face ) ) )
2698#else
2699#define IS_DEFAULT_INSTANCE 1
2700#endif
2701
2702
2703 FT_TRACE1(( "TT_Load_Glyph: glyph index %d\n", glyph_index ));
2704
2705#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
2706
2707 /* try to load embedded bitmap (if any) */
2708 if ( size->strike_index != 0xFFFFFFFFUL &&
2709 ( load_flags & FT_LOAD_NO_BITMAP ) == 0 &&
2711 {
2712 error = load_sbit_image( size, glyph, glyph_index, load_flags );
2713 if ( FT_ERR_EQ( error, Missing_Bitmap ) )
2714 {
2715 /* the bitmap strike is incomplete and misses the requested glyph; */
2716 /* if we have a bitmap-only font, return an empty glyph */
2717 if ( !FT_IS_SCALABLE( glyph->face ) )
2718 {
2719 TT_Face face = (TT_Face)glyph->face;
2720 FT_Short left_bearing = 0, top_bearing = 0;
2721 FT_UShort advance_width = 0, advance_height = 0;
2722
2723
2724 /* to return an empty glyph, however, we need metrics data */
2725 /* from the `hmtx' (or `vmtx') table; the assumption is that */
2726 /* empty glyphs are missing intentionally, representing */
2727 /* whitespace - not having at least horizontal metrics is */
2728 /* thus considered an error */
2729 if ( !face->horz_metrics_size )
2730 return error;
2731
2732 /* we now construct an empty bitmap glyph */
2733 TT_Get_HMetrics( face, glyph_index,
2734 &left_bearing,
2735 &advance_width );
2736 TT_Get_VMetrics( face, glyph_index,
2737 0,
2738 &top_bearing,
2739 &advance_height );
2740
2741 glyph->outline.n_points = 0;
2742 glyph->outline.n_contours = 0;
2743
2744 glyph->metrics.width = 0;
2745 glyph->metrics.height = 0;
2746
2747 glyph->metrics.horiBearingX = left_bearing;
2748 glyph->metrics.horiBearingY = 0;
2749 glyph->metrics.horiAdvance = advance_width;
2750
2751 glyph->metrics.vertBearingX = 0;
2752 glyph->metrics.vertBearingY = top_bearing;
2753 glyph->metrics.vertAdvance = advance_height;
2754
2755 glyph->format = FT_GLYPH_FORMAT_BITMAP;
2757
2758 glyph->bitmap_left = 0;
2759 glyph->bitmap_top = 0;
2760
2761 return FT_Err_Ok;
2762 }
2763 }
2764 else if ( error )
2765 {
2766 /* return error if font is not scalable */
2767 if ( !FT_IS_SCALABLE( glyph->face ) )
2768 return error;
2769 }
2770 else
2771 {
2772 if ( FT_IS_SCALABLE( glyph->face ) )
2773 {
2774 /* for the bbox we need the header only */
2775 (void)tt_loader_init( &loader, size, glyph, load_flags, TRUE );
2776 (void)load_truetype_glyph( &loader, glyph_index, 0, TRUE );
2777 tt_loader_done( &loader );
2778 glyph->linearHoriAdvance = loader.linear;
2779 glyph->linearVertAdvance = loader.vadvance;
2780
2781 /* sanity checks: if `xxxAdvance' in the sbit metric */
2782 /* structure isn't set, use `linearXXXAdvance' */
2783 if ( !glyph->metrics.horiAdvance && glyph->linearHoriAdvance )
2784 glyph->metrics.horiAdvance =
2786 size->metrics->x_scale );
2787 if ( !glyph->metrics.vertAdvance && glyph->linearVertAdvance )
2788 glyph->metrics.vertAdvance =
2790 size->metrics->y_scale );
2791 }
2792
2793 return FT_Err_Ok;
2794 }
2795 }
2796
2797#endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */
2798
2799 /* if FT_LOAD_NO_SCALE is not set, `ttmetrics' must be valid */
2800 if ( !( load_flags & FT_LOAD_NO_SCALE ) && !size->ttmetrics.valid )
2801 {
2802 error = FT_THROW( Invalid_Size_Handle );
2803 goto Exit;
2804 }
2805
2806 if ( load_flags & FT_LOAD_SBITS_ONLY )
2807 {
2808 error = FT_THROW( Invalid_Argument );
2809 goto Exit;
2810 }
2811
2812 error = tt_loader_init( &loader, size, glyph, load_flags, FALSE );
2813 if ( error )
2814 goto Exit;
2815
2817 glyph->num_subglyphs = 0;
2818 glyph->outline.flags = 0;
2819
2820 /* main loading loop */
2821 error = load_truetype_glyph( &loader, glyph_index, 0, FALSE );
2822 if ( !error )
2823 {
2824 if ( glyph->format == FT_GLYPH_FORMAT_COMPOSITE )
2825 {
2826 glyph->num_subglyphs = loader.gloader->base.num_subglyphs;
2827 glyph->subglyphs = loader.gloader->base.subglyphs;
2828 }
2829 else
2830 {
2831 glyph->outline = loader.gloader->base.outline;
2832 glyph->outline.flags &= ~FT_OUTLINE_SINGLE_PASS;
2833
2834 /* Translate array so that (0,0) is the glyph's origin. Note */
2835 /* that this behaviour is independent on the value of bit 1 of */
2836 /* the `flags' field in the `head' table -- at least major */
2837 /* applications like Acroread indicate that. */
2838 if ( loader.pp1.x )
2839 FT_Outline_Translate( &glyph->outline, -loader.pp1.x, 0 );
2840 }
2841
2842#ifdef TT_USE_BYTECODE_INTERPRETER
2843
2844 if ( IS_HINTED( load_flags ) )
2845 {
2846 if ( loader.exec->GS.scan_control )
2847 {
2848 /* convert scan conversion mode to FT_OUTLINE_XXX flags */
2849 switch ( loader.exec->GS.scan_type )
2850 {
2851 case 0: /* simple drop-outs including stubs */
2853 break;
2854 case 1: /* simple drop-outs excluding stubs */
2855 /* nothing; it's the default rendering mode */
2856 break;
2857 case 4: /* smart drop-outs including stubs */
2860 break;
2861 case 5: /* smart drop-outs excluding stubs */
2863 break;
2864
2865 default: /* no drop-out control */
2867 break;
2868 }
2869 }
2870 else
2872 }
2873
2874#endif /* TT_USE_BYTECODE_INTERPRETER */
2875
2876 error = compute_glyph_metrics( &loader, glyph_index );
2877 }
2878
2879 tt_loader_done( &loader );
2880
2881 /* Set the `high precision' bit flag. */
2882 /* This is _critical_ to get correct output for monochrome */
2883 /* TrueType glyphs at all sizes using the bytecode interpreter. */
2884 /* */
2885 if ( !( load_flags & FT_LOAD_NO_SCALE ) &&
2886 size->metrics->y_ppem < 24 )
2888
2889 Exit:
2890#ifdef FT_DEBUG_LEVEL_TRACE
2891 if ( error )
2892 FT_TRACE1(( " failed (error code 0x%x)\n",
2893 error ));
2894#endif
2895
2896 return error;
2897 }
#define FT_LOAD_SBITS_ONLY
Definition: freetype.h:3032
#define FT_LOAD_NO_BITMAP
Definition: freetype.h:3012
#define FT_IS_SCALABLE(face)
Definition: freetype.h:1312
#define FT_OUTLINE_SMART_DROPOUTS
Definition: ftimage.h:432
@ FT_PIXEL_MODE_MONO
Definition: ftimage.h:183
#define FT_OUTLINE_IGNORE_DROPOUTS
Definition: ftimage.h:431
#define FT_OUTLINE_INCLUDE_STUBS
Definition: ftimage.h:433
#define FT_OUTLINE_HIGH_PRECISION
Definition: ftimage.h:435
FT_Outline_Translate(const FT_Outline *outline, FT_Pos xOffset, FT_Pos yOffset)
Definition: ftoutln.c:528
smooth FT_Module_Constructor FT_Module_Destructor FT_Module_Requester FT_GLYPH_FORMAT_OUTLINE
Definition: ftsmooth.c:426
#define FT_ERR_EQ(x, e)
Definition: fttypes.h:591
unsigned char pixel_mode
Definition: ftimage.h:268
FT_Int bitmap_top
Definition: freetype.h:1925
FT_SubGlyph subglyphs
Definition: freetype.h:1930
FT_UInt num_subglyphs
Definition: freetype.h:1929
FT_Int bitmap_left
Definition: freetype.h:1924
FT_Bitmap bitmap
Definition: freetype.h:1923
int flags
Definition: ftimage.h:343
FT_Bool scan_control
Definition: ttobjs.h:91
static void tt_loader_done(TT_Loader loader)
Definition: ttgload.c:2650
static FT_Error tt_loader_init(TT_Loader loader, TT_Size size, TT_GlyphSlot glyph, FT_Int32 load_flags, FT_Bool glyf_table_only)
Definition: ttgload.c:2352
#define IS_DEFAULT_INSTANCE
static FT_Error compute_glyph_metrics(TT_Loader loader, FT_UInt glyph_index)
Definition: ttgload.c:2105
struct TT_FaceRec_ * TT_Face
Definition: tttypes.h:973

Referenced by tt_glyph_load().

◆ TT_Load_Glyph_Header()

TT_Load_Glyph_Header ( TT_Loader  loader)

Definition at line 298 of file ttgload.c.

299 {
300 FT_Byte* p = loader->cursor;
301 FT_Byte* limit = loader->limit;
302
303
304 if ( p + 10 > limit )
305 return FT_THROW( Invalid_Outline );
306
307 loader->n_contours = FT_NEXT_SHORT( p );
308
309 loader->bbox.xMin = FT_NEXT_SHORT( p );
310 loader->bbox.yMin = FT_NEXT_SHORT( p );
311 loader->bbox.xMax = FT_NEXT_SHORT( p );
312 loader->bbox.yMax = FT_NEXT_SHORT( p );
313
314 FT_TRACE5(( " # of contours: %d\n", loader->n_contours ));
315 FT_TRACE5(( " xMin: %4d xMax: %4d\n", loader->bbox.xMin,
316 loader->bbox.xMax ));
317 FT_TRACE5(( " yMin: %4d yMax: %4d\n", loader->bbox.yMin,
318 loader->bbox.yMax ));
319 loader->cursor = p;
320
321 return FT_Err_Ok;
322 }

Referenced by TT_Init_Glyph_Loading().

◆ TT_Load_Simple_Glyph()

TT_Load_Simple_Glyph ( TT_Loader  load)

Definition at line 326 of file ttgload.c.

327 {
329 FT_Byte* p = load->cursor;
330 FT_Byte* limit = load->limit;
331 FT_GlyphLoader gloader = load->gloader;
332 FT_Int n_contours = load->n_contours;
334 FT_UShort n_ins;
335 FT_Int n_points;
336
337 FT_Byte *flag, *flag_limit;
338 FT_Byte c, count;
339 FT_Vector *vec, *vec_limit;
340 FT_Pos x;
341 FT_Short *cont, *cont_limit, prev_cont;
342 FT_Int xy_size = 0;
343
344
345 /* check that we can add the contours to the glyph */
346 error = FT_GLYPHLOADER_CHECK_POINTS( gloader, 0, n_contours );
347 if ( error )
348 goto Fail;
349
350 /* reading the contours' endpoints & number of points */
351 cont = gloader->current.outline.contours;
352 cont_limit = cont + n_contours;
353
354 /* check space for contours array + instructions count */
355 if ( n_contours >= 0xFFF || p + ( n_contours + 1 ) * 2 > limit )
356 goto Invalid_Outline;
357
358 prev_cont = FT_NEXT_SHORT( p );
359
360 if ( n_contours > 0 )
361 cont[0] = prev_cont;
362
363 if ( prev_cont < 0 )
364 goto Invalid_Outline;
365
366 for ( cont++; cont < cont_limit; cont++ )
367 {
368 cont[0] = FT_NEXT_SHORT( p );
369 if ( cont[0] <= prev_cont )
370 {
371 /* unordered contours: this is invalid */
372 goto Invalid_Outline;
373 }
374 prev_cont = cont[0];
375 }
376
377 n_points = 0;
378 if ( n_contours > 0 )
379 {
380 n_points = cont[-1] + 1;
381 if ( n_points < 0 )
382 goto Invalid_Outline;
383 }
384
385 /* note that we will add four phantom points later */
386 error = FT_GLYPHLOADER_CHECK_POINTS( gloader, n_points + 4, 0 );
387 if ( error )
388 goto Fail;
389
390 /* reading the bytecode instructions */
391 load->glyph->control_len = 0;
392 load->glyph->control_data = NULL;
393
394 if ( p + 2 > limit )
395 goto Invalid_Outline;
396
397 n_ins = FT_NEXT_USHORT( p );
398
399 FT_TRACE5(( " Instructions size: %u\n", n_ins ));
400
401#ifdef TT_USE_BYTECODE_INTERPRETER
402
403 if ( IS_HINTED( load->load_flags ) )
404 {
405 FT_ULong tmp;
406
407
408 /* check instructions size */
409 if ( ( limit - p ) < n_ins )
410 {
411 FT_TRACE1(( "TT_Load_Simple_Glyph: instruction count mismatch\n" ));
412 error = FT_THROW( Too_Many_Hints );
413 goto Fail;
414 }
415
416 /* we don't trust `maxSizeOfInstructions' in the `maxp' table */
417 /* and thus update the bytecode array size by ourselves */
418
419 tmp = load->exec->glyphSize;
420 error = Update_Max( load->exec->memory,
421 &tmp,
422 sizeof ( FT_Byte ),
423 (void*)&load->exec->glyphIns,
424 n_ins );
425
426 load->exec->glyphSize = (FT_UShort)tmp;
427 if ( error )
428 return error;
429
430 load->glyph->control_len = n_ins;
431 load->glyph->control_data = load->exec->glyphIns;
432
433 if ( n_ins )
434 FT_MEM_COPY( load->exec->glyphIns, p, (FT_Long)n_ins );
435 }
436
437#endif /* TT_USE_BYTECODE_INTERPRETER */
438
439 p += n_ins;
440
441 outline = &gloader->current.outline;
442
443 /* reading the point tags */
444 flag = (FT_Byte*)outline->tags;
445 flag_limit = flag + n_points;
446
447 FT_ASSERT( flag );
448
449 while ( flag < flag_limit )
450 {
451 if ( p + 1 > limit )
452 goto Invalid_Outline;
453
454 *flag++ = c = FT_NEXT_BYTE( p );
455 if ( c & 8 )
456 {
457 if ( p + 1 > limit )
458 goto Invalid_Outline;
459
460 count = FT_NEXT_BYTE( p );
461 if ( flag + (FT_Int)count > flag_limit )
462 goto Invalid_Outline;
463
464 for ( ; count > 0; count-- )
465 *flag++ = c;
466 }
467 }
468
469 /* reading the X coordinates */
470
471 vec = outline->points;
472 vec_limit = vec + n_points;
473 flag = (FT_Byte*)outline->tags;
474 x = 0;
475
476 if ( p + xy_size > limit )
477 goto Invalid_Outline;
478
479 for ( ; vec < vec_limit; vec++, flag++ )
480 {
481 FT_Pos y = 0;
482 FT_Byte f = *flag;
483
484
485 if ( f & 2 )
486 {
487 if ( p + 1 > limit )
488 goto Invalid_Outline;
489
490 y = (FT_Pos)FT_NEXT_BYTE( p );
491 if ( ( f & 16 ) == 0 )
492 y = -y;
493 }
494 else if ( ( f & 16 ) == 0 )
495 {
496 if ( p + 2 > limit )
497 goto Invalid_Outline;
498
499 y = (FT_Pos)FT_NEXT_SHORT( p );
500 }
501
502 x += y;
503 vec->x = x;
504 /* the cast is for stupid compilers */
505 *flag = (FT_Byte)( f & ~( 2 | 16 ) );
506 }
507
508 /* reading the Y coordinates */
509
510 vec = gloader->current.outline.points;
511 vec_limit = vec + n_points;
512 flag = (FT_Byte*)outline->tags;
513 x = 0;
514
515 for ( ; vec < vec_limit; vec++, flag++ )
516 {
517 FT_Pos y = 0;
518 FT_Byte f = *flag;
519
520
521 if ( f & 4 )
522 {
523 if ( p + 1 > limit )
524 goto Invalid_Outline;
525
526 y = (FT_Pos)FT_NEXT_BYTE( p );
527 if ( ( f & 32 ) == 0 )
528 y = -y;
529 }
530 else if ( ( f & 32 ) == 0 )
531 {
532 if ( p + 2 > limit )
533 goto Invalid_Outline;
534
535 y = (FT_Pos)FT_NEXT_SHORT( p );
536 }
537
538 x += y;
539 vec->y = x;
540 /* the cast is for stupid compilers */
541 *flag = (FT_Byte)( f & FT_CURVE_TAG_ON );
542 }
543
544 outline->n_points = (FT_Short)n_points;
545 outline->n_contours = (FT_Short)n_contours;
546
547 load->cursor = p;
548
549 Fail:
550 return error;
551
552 Invalid_Outline:
553 error = FT_THROW( Invalid_Outline );
554 goto Fail;
555 }
FT_Vector * vec
Definition: ftbbox.c:448
#define FT_ASSERT(condition)
Definition: ftdebug.h:211
#define FT_GLYPHLOADER_CHECK_POINTS(_loader, _points, _contours)
Definition: ftgloadr.h:118
#define FT_CURVE_TAG_ON
Definition: ftimage.h:453
#define FT_MEM_COPY(dest, source, count)
Definition: ftmemory.h:228
const GLubyte * c
Definition: glext.h:8905
GLfloat f
Definition: glext.h:7540
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean flag
Definition: glfuncs.h:52
#define c
Definition: ke_i.h:80
#define for
Definition: utility.h:88
int load
Definition: msacm.c:1365
short * contours
Definition: ftimage.h:341
FT_Vector * points
Definition: ftimage.h:339
ActualNumberDriverObjects * sizeof(PDRIVER_OBJECT)) PDRIVER_OBJECT *DriverObjectList

Referenced by TT_Init_Glyph_Loading().

◆ tt_loader_done()

static void tt_loader_done ( TT_Loader  loader)
static

Definition at line 2650 of file ttgload.c.

2651 {
2652 FT_List_Finalize( &loader->composites,
2653 NULL,
2654 loader->face->root.memory,
2655 NULL );
2656 }
FT_List_Finalize(FT_List list, FT_List_Destructor destroy, FT_Memory memory, void *user)
Definition: ftutil.c:413
FT_Memory memory
Definition: freetype.h:1112
FT_FaceRec root
Definition: tttypes.h:1393

Referenced by TT_Load_Glyph().

◆ tt_loader_init()

static FT_Error tt_loader_init ( TT_Loader  loader,
TT_Size  size,
TT_GlyphSlot  glyph,
FT_Int32  load_flags,
FT_Bool  glyf_table_only 
)
static

Definition at line 2352 of file ttgload.c.

2357 {
2358 TT_Face face;
2360
2361#ifdef TT_USE_BYTECODE_INTERPRETER
2363 FT_Bool pedantic = FT_BOOL( load_flags & FT_LOAD_PEDANTIC );
2364#if defined TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY || \
2365 defined TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
2367#endif
2368#endif
2369
2370
2371 face = (TT_Face)glyph->face;
2372 stream = face->root.stream;
2373
2374 FT_ZERO( loader );
2375
2376#ifdef TT_USE_BYTECODE_INTERPRETER
2377
2378 /* load execution context */
2379 if ( IS_HINTED( load_flags ) && !glyf_table_only )
2380 {
2381 TT_ExecContext exec;
2382 FT_Bool grayscale = TRUE;
2383#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
2384 FT_Bool subpixel_hinting_lean;
2385 FT_Bool grayscale_cleartype;
2386#endif
2387
2388#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
2389 FT_Bool subpixel_hinting = FALSE;
2390
2391#if 0
2392 /* not used yet */
2393 FT_Bool compatible_widths;
2394 FT_Bool symmetrical_smoothing;
2395 FT_Bool bgr;
2396 FT_Bool vertical_lcd;
2397 FT_Bool subpixel_positioned;
2398 FT_Bool gray_cleartype;
2399#endif
2400#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
2401
2402 FT_Bool reexecute = FALSE;
2403
2404
2405 if ( size->bytecode_ready < 0 || size->cvt_ready < 0 )
2406 {
2407 error = tt_size_ready_bytecode( size, pedantic );
2408 if ( error )
2409 return error;
2410 }
2411 else if ( size->bytecode_ready )
2412 return size->bytecode_ready;
2413 else if ( size->cvt_ready )
2414 return size->cvt_ready;
2415
2416 /* query new execution context */
2417 exec = size->context;
2418 if ( !exec )
2419 return FT_THROW( Could_Not_Find_Context );
2420
2421#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
2422 if ( driver->interpreter_version == TT_INTERPRETER_VERSION_40 )
2423 {
2424 subpixel_hinting_lean =
2425 FT_BOOL( FT_LOAD_TARGET_MODE( load_flags ) !=
2427 grayscale_cleartype =
2428 FT_BOOL( subpixel_hinting_lean &&
2429 !( ( load_flags &
2431 ( load_flags &
2433 exec->vertical_lcd_lean =
2434 FT_BOOL( subpixel_hinting_lean &&
2435 ( load_flags &
2437 }
2438 else
2439 {
2440 subpixel_hinting_lean = FALSE;
2441 grayscale_cleartype = FALSE;
2442 exec->vertical_lcd_lean = FALSE;
2443 }
2444#endif
2445
2446#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
2447
2448 if ( driver->interpreter_version == TT_INTERPRETER_VERSION_38 )
2449 {
2450 subpixel_hinting = FT_BOOL( ( FT_LOAD_TARGET_MODE( load_flags ) !=
2452 SPH_OPTION_SET_SUBPIXEL );
2453
2454 if ( subpixel_hinting )
2455 grayscale = FALSE;
2456 else if ( SPH_OPTION_SET_GRAYSCALE )
2457 {
2458 grayscale = TRUE;
2459 subpixel_hinting = FALSE;
2460 }
2461 else
2462 grayscale = FALSE;
2463
2464 if ( FT_IS_TRICKY( glyph->face ) )
2465 subpixel_hinting = FALSE;
2466
2467 exec->ignore_x_mode = subpixel_hinting || grayscale;
2468 exec->rasterizer_version = SPH_OPTION_SET_RASTERIZER_VERSION;
2469 if ( exec->sph_tweak_flags & SPH_TWEAK_RASTERIZER_35 )
2470 exec->rasterizer_version = TT_INTERPRETER_VERSION_35;
2471
2472#if 1
2473 exec->compatible_widths = SPH_OPTION_SET_COMPATIBLE_WIDTHS;
2474 exec->symmetrical_smoothing = TRUE;
2475 exec->bgr = FALSE;
2476 exec->vertical_lcd = FALSE;
2477 exec->subpixel_positioned = TRUE;
2478 exec->gray_cleartype = FALSE;
2479#else /* 0 */
2480 exec->compatible_widths =
2481 FT_BOOL( FT_LOAD_TARGET_MODE( load_flags ) !=
2482 TT_LOAD_COMPATIBLE_WIDTHS );
2483 exec->symmetrical_smoothing =
2484 FT_BOOL( FT_LOAD_TARGET_MODE( load_flags ) !=
2485 TT_LOAD_SYMMETRICAL_SMOOTHING );
2486 exec->bgr =
2487 FT_BOOL( FT_LOAD_TARGET_MODE( load_flags ) !=
2488 TT_LOAD_BGR );
2489 exec->vertical_lcd =
2490 FT_BOOL( FT_LOAD_TARGET_MODE( load_flags ) !=
2491 TT_LOAD_VERTICAL_LCD );
2492 exec->subpixel_positioned =
2493 FT_BOOL( FT_LOAD_TARGET_MODE( load_flags ) !=
2494 TT_LOAD_SUBPIXEL_POSITIONED );
2495 exec->gray_cleartype =
2496 FT_BOOL( FT_LOAD_TARGET_MODE( load_flags ) !=
2497 TT_LOAD_GRAY_CLEARTYPE );
2498#endif /* 0 */
2499
2500 }
2501 else
2502
2503#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
2504
2505#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
2506 if ( driver->interpreter_version == TT_INTERPRETER_VERSION_40 )
2507 grayscale = FT_BOOL( !subpixel_hinting_lean &&
2508 FT_LOAD_TARGET_MODE( load_flags ) !=
2510 else
2511#endif
2512 grayscale = FT_BOOL( FT_LOAD_TARGET_MODE( load_flags ) !=
2514
2515 error = TT_Load_Context( exec, face, size );
2516 if ( error )
2517 return error;
2518
2519#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
2520
2521 if ( driver->interpreter_version == TT_INTERPRETER_VERSION_38 )
2522 {
2523 /* a change from mono to subpixel rendering (and vice versa) */
2524 /* requires a re-execution of the CVT program */
2525 if ( subpixel_hinting != exec->subpixel_hinting )
2526 {
2527 FT_TRACE4(( "tt_loader_init: subpixel hinting change,"
2528 " re-executing `prep' table\n" ));
2529
2530 exec->subpixel_hinting = subpixel_hinting;
2531 reexecute = TRUE;
2532 }
2533
2534 /* a change from mono to grayscale rendering (and vice versa) */
2535 /* requires a re-execution of the CVT program */
2536 if ( grayscale != exec->grayscale )
2537 {
2538 FT_TRACE4(( "tt_loader_init: grayscale hinting change,"
2539 " re-executing `prep' table\n" ));
2540
2541 exec->grayscale = grayscale;
2542 reexecute = TRUE;
2543 }
2544 }
2545 else
2546
2547#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
2548
2549 {
2550
2551#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
2552 if ( driver->interpreter_version == TT_INTERPRETER_VERSION_40 )
2553 {
2554 /* a change from mono to subpixel rendering (and vice versa) */
2555 /* requires a re-execution of the CVT program */
2556 if ( subpixel_hinting_lean != exec->subpixel_hinting_lean )
2557 {
2558 FT_TRACE4(( "tt_loader_init: subpixel hinting change,"
2559 " re-executing `prep' table\n" ));
2560
2561 exec->subpixel_hinting_lean = subpixel_hinting_lean;
2562 reexecute = TRUE;
2563 }
2564
2565 /* a change from colored to grayscale subpixel rendering (and */
2566 /* vice versa) requires a re-execution of the CVT program */
2567 if ( grayscale_cleartype != exec->grayscale_cleartype )
2568 {
2569 FT_TRACE4(( "tt_loader_init: grayscale subpixel hinting change,"
2570 " re-executing `prep' table\n" ));
2571
2572 exec->grayscale_cleartype = grayscale_cleartype;
2573 reexecute = TRUE;
2574 }
2575 }
2576#endif
2577
2578 /* a change from mono to grayscale rendering (and vice versa) */
2579 /* requires a re-execution of the CVT program */
2580 if ( grayscale != exec->grayscale )
2581 {
2582 FT_TRACE4(( "tt_loader_init: grayscale hinting change,"
2583 " re-executing `prep' table\n" ));
2584
2585 exec->grayscale = grayscale;
2586 reexecute = TRUE;
2587 }
2588 }
2589
2590 if ( reexecute )
2591 {
2592 FT_UInt i;
2593
2594
2595 for ( i = 0; i < size->cvt_size; i++ )
2596 size->cvt[i] = FT_MulFix( face->cvt[i], size->ttmetrics.scale );
2597 error = tt_size_run_prep( size, pedantic );
2598 if ( error )
2599 return error;
2600 }
2601
2602 /* check whether the cvt program has disabled hinting */
2603 if ( exec->GS.instruct_control & 1 )
2604 load_flags |= FT_LOAD_NO_HINTING;
2605
2606 /* load default graphics state -- if needed */
2607 if ( exec->GS.instruct_control & 2 )
2609
2610#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
2611 /* check whether we have a font hinted for ClearType -- */
2612 /* note that this flag can also be modified in a glyph's bytecode */
2613 if ( driver->interpreter_version == TT_INTERPRETER_VERSION_38 &&
2614 exec->GS.instruct_control & 4 )
2615 exec->ignore_x_mode = 0;
2616#endif
2617
2618 exec->pedantic_hinting = FT_BOOL( load_flags & FT_LOAD_PEDANTIC );
2619 loader->exec = exec;
2620 loader->instructions = exec->glyphIns;
2621 }
2622
2623#endif /* TT_USE_BYTECODE_INTERPRETER */
2624
2625 /* get face's glyph loader */
2626 if ( !glyf_table_only )
2627 {
2628 FT_GlyphLoader gloader = glyph->internal->loader;
2629
2630
2631 FT_GlyphLoader_Rewind( gloader );
2632 loader->gloader = gloader;
2633 }
2634
2635 loader->load_flags = (FT_ULong)load_flags;
2636
2637 loader->face = face;
2638 loader->size = size;
2639 loader->glyph = (FT_GlyphSlot)glyph;
2640 loader->stream = stream;
2641
2642 loader->composites.head = NULL;
2643 loader->composites.tail = NULL;
2644
2645 return FT_Err_Ok;
2646 }
WORD face[3]
Definition: mesh.c:4747
#define FT_LOAD_TARGET_LCD_V
Definition: freetype.h:3124
#define FT_LOAD_NO_HINTING
Definition: freetype.h:3010
struct FT_GlyphSlotRec_ * FT_GlyphSlot
Definition: freetype.h:554
#define FT_LOAD_TARGET_LCD
Definition: freetype.h:3123
#define FT_IS_TRICKY(face)
Definition: freetype.h:1474
#define FT_LOAD_PEDANTIC
Definition: freetype.h:3016
#define TT_INTERPRETER_VERSION_35
Definition: ftdriver.h:747
FT_GlyphLoader_Rewind(FT_GlyphLoader loader)
Definition: ftgloadr.c:88
FT_Slot_Internal internal
Definition: freetype.h:1940
FT_ListNode head
Definition: fttypes.h:569
FT_ListNode tail
Definition: fttypes.h:570
FT_GlyphLoader loader
Definition: ftobjs.h:467
FT_Bool grayscale
Definition: ttinterp.h:251
FT_Byte instruct_control
Definition: ttobjs.h:86
FT_Byte * instructions
Definition: tttypes.h:1662
const TT_GraphicsState tt_default_graphics_state
int pedantic
Definition: widl.c:113

Referenced by TT_Load_Glyph().

◆ tt_loader_set_pp()

static void tt_loader_set_pp ( TT_Loader  loader)
static

Definition at line 1433 of file ttgload.c.

1434 {
1435 FT_Bool subpixel_hinting = 0;
1436 FT_Bool grayscale = 0;
1437 FT_Bool use_aw_2 = 0;
1438
1439#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
1441#endif
1442
1443
1444#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
1445 if ( driver->interpreter_version == TT_INTERPRETER_VERSION_38 )
1446 {
1447 subpixel_hinting = loader->exec ? loader->exec->subpixel_hinting
1448 : 0;
1449 grayscale = loader->exec ? loader->exec->grayscale
1450 : 0;
1451 }
1452#endif
1453#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
1454 if ( driver->interpreter_version == TT_INTERPRETER_VERSION_40 )
1455 {
1456 subpixel_hinting = loader->exec ? loader->exec->subpixel_hinting_lean
1457 : 0;
1458 grayscale = loader->exec ? loader->exec->grayscale_cleartype
1459 : 0;
1460 }
1461#endif
1462
1463 use_aw_2 = (FT_Bool)( subpixel_hinting && grayscale );
1464
1465 loader->pp1.x = loader->bbox.xMin - loader->left_bearing;
1466 loader->pp1.y = 0;
1467 loader->pp2.x = loader->pp1.x + loader->advance;
1468 loader->pp2.y = 0;
1469
1470 loader->pp3.x = use_aw_2 ? loader->advance / 2 : 0;
1471 loader->pp3.y = loader->bbox.yMax + loader->top_bearing;
1472 loader->pp4.x = use_aw_2 ? loader->advance / 2 : 0;
1473 loader->pp4.y = loader->pp3.y - loader->vadvance;
1474 }

Referenced by load_truetype_glyph().

◆ tt_prepare_zone()

static void tt_prepare_zone ( TT_GlyphZone  zone,
FT_GlyphLoad  load,
FT_UInt  start_point,
FT_UInt  start_contour 
)
static

Definition at line 753 of file ttgload.c.

757 {
758 zone->n_points = (FT_UShort)load->outline.n_points -
759 (FT_UShort)start_point;
760 zone->n_contours = load->outline.n_contours -
761 (FT_Short)start_contour;
762 zone->org = load->extra_points + start_point;
763 zone->cur = load->outline.points + start_point;
764 zone->orus = load->extra_points2 + start_point;
765 zone->tags = (FT_Byte*)load->outline.tags + start_point;
766 zone->contours = (FT_UShort*)load->outline.contours + start_contour;
767 zone->first_point = (FT_UShort)start_point;
768 }

Referenced by TT_Process_Composite_Glyph(), and TT_Process_Simple_Glyph().

◆ TT_Process_Composite_Component()

static FT_Error TT_Process_Composite_Component ( TT_Loader  loader,
FT_SubGlyph  subglyph,
FT_UInt  start_point,
FT_UInt  num_base_points 
)
static

Definition at line 1084 of file ttgload.c.

1088 {
1089 FT_GlyphLoader gloader = loader->gloader;
1091 FT_Bool have_scale;
1092 FT_Pos x, y;
1093
1094
1095 current.points = gloader->base.outline.points +
1096 num_base_points;
1097 current.n_points = gloader->base.outline.n_points -
1098 (short)num_base_points;
1099
1100 have_scale = FT_BOOL( subglyph->flags & ( WE_HAVE_A_SCALE |
1102 WE_HAVE_A_2X2 ) );
1103
1104 /* perform the transform required for this subglyph */
1105 if ( have_scale )
1106 FT_Outline_Transform( &current, &subglyph->transform );
1107
1108 /* get offset */
1109 if ( !( subglyph->flags & ARGS_ARE_XY_VALUES ) )
1110 {
1111 FT_UInt num_points = (FT_UInt)gloader->base.outline.n_points;
1112 FT_UInt k = (FT_UInt)subglyph->arg1;
1113 FT_UInt l = (FT_UInt)subglyph->arg2;
1114 FT_Vector* p1;
1115 FT_Vector* p2;
1116
1117
1118 /* match l-th point of the newly loaded component to the k-th point */
1119 /* of the previously loaded components. */
1120
1121 /* change to the point numbers used by our outline */
1122 k += start_point;
1123 l += num_base_points;
1124 if ( k >= num_base_points ||
1125 l >= num_points )
1126 return FT_THROW( Invalid_Composite );
1127
1128 p1 = gloader->base.outline.points + k;
1129 p2 = gloader->base.outline.points + l;
1130
1131 x = p1->x - p2->x;
1132 y = p1->y - p2->y;
1133 }
1134 else
1135 {
1136 x = subglyph->arg1;
1137 y = subglyph->arg2;
1138
1139 if ( !x && !y )
1140 return FT_Err_Ok;
1141
1142 /* Use a default value dependent on */
1143 /* TT_CONFIG_OPTION_COMPONENT_OFFSET_SCALED. This is useful for old */
1144 /* TT fonts which don't set the xxx_COMPONENT_OFFSET bit. */
1145
1146 if ( have_scale &&
1147#ifdef TT_CONFIG_OPTION_COMPONENT_OFFSET_SCALED
1148 !( subglyph->flags & UNSCALED_COMPONENT_OFFSET ) )
1149#else
1150 ( subglyph->flags & SCALED_COMPONENT_OFFSET ) )
1151#endif
1152 {
1153
1154#if 0
1155
1156 /*******************************************************************/
1157 /* */
1158 /* This algorithm is what Apple documents. But it doesn't work. */
1159 /* */
1160 int a = subglyph->transform.xx > 0 ? subglyph->transform.xx
1161 : -subglyph->transform.xx;
1162 int b = subglyph->transform.yx > 0 ? subglyph->transform.yx
1163 : -subglyph->transform.yx;
1164 int c = subglyph->transform.xy > 0 ? subglyph->transform.xy
1165 : -subglyph->transform.xy;
1166 int d = subglyph->transform.yy > 0 ? subglyph->transform.yy
1167 : -subglyph->transform.yy;
1168 int m = a > b ? a : b;
1169 int n = c > d ? c : d;
1170
1171
1172 if ( a - b <= 33 && a - b >= -33 )
1173 m *= 2;
1174 if ( c - d <= 33 && c - d >= -33 )
1175 n *= 2;
1176 x = FT_MulFix( x, m );
1177 y = FT_MulFix( y, n );
1178
1179#else /* 1 */
1180
1181 /*******************************************************************/
1182 /* */
1183 /* This algorithm is a guess and works much better than the above. */
1184 /* */
1185 FT_Fixed mac_xscale = FT_Hypot( subglyph->transform.xx,
1186 subglyph->transform.xy );
1187 FT_Fixed mac_yscale = FT_Hypot( subglyph->transform.yy,
1188 subglyph->transform.yx );
1189
1190
1191 x = FT_MulFix( x, mac_xscale );
1192 y = FT_MulFix( y, mac_yscale );
1193
1194#endif /* 1 */
1195
1196 }
1197
1198 if ( !( loader->load_flags & FT_LOAD_NO_SCALE ) )
1199 {
1200 FT_Fixed x_scale = loader->size->metrics->x_scale;
1201 FT_Fixed y_scale = loader->size->metrics->y_scale;
1202
1203
1204 x = FT_MulFix( x, x_scale );
1205 y = FT_MulFix( y, y_scale );
1206
1207 if ( subglyph->flags & ROUND_XY_TO_GRID )
1208 {
1209 TT_Face face = loader->face;
1211
1212
1213 if ( IS_HINTED( loader->load_flags ) )
1214 {
1215 /*
1216 * We round the horizontal offset only if there is hinting along
1217 * the x axis; this corresponds to integer advance width values.
1218 *
1219 * Theoretically, a glyph's bytecode can toggle ClearType's
1220 * `backward compatibility' mode, which would allow modification
1221 * of the advance width. In reality, however, applications
1222 * neither allow nor expect modified advance widths if sub-pixel
1223 * rendering is active.
1224 *
1225 */
1226 if ( driver->interpreter_version == TT_INTERPRETER_VERSION_35 )
1227 x = FT_PIX_ROUND( x );
1228
1229 y = FT_PIX_ROUND( y );
1230 }
1231 }
1232 }
1233 }
1234
1235 if ( x || y )
1237
1238 return FT_Err_Ok;
1239 }
r l[0]
Definition: byte_order.h:168
FT_Hypot(FT_Fixed x, FT_Fixed y)
Definition: ftcalc.c:155
FT_Outline_Transform(const FT_Outline *outline, const FT_Matrix *matrix)
Definition: ftoutln.c:711
GLboolean GLboolean GLboolean b
Definition: glext.h:6204
GLboolean GLboolean GLboolean GLboolean a
Definition: glext.h:6204
const GLfloat * m
Definition: glext.h:10848
#define d
Definition: ke_i.h:81
#define a
Definition: ke_i.h:78
#define b
Definition: ke_i.h:79
struct task_struct * current
Definition: linux.c:32
int k
Definition: mpi.c:3369
#define UNSCALED_COMPONENT_OFFSET
Definition: ttgload.c:67
#define ROUND_XY_TO_GRID
Definition: ttgload.c:57
#define SCALED_COMPONENT_OFFSET
Definition: ttgload.c:66

Referenced by load_truetype_glyph().

◆ TT_Process_Composite_Glyph()

static FT_Error TT_Process_Composite_Glyph ( TT_Loader  loader,
FT_UInt  start_point,
FT_UInt  start_contour 
)
static

Definition at line 1253 of file ttgload.c.

1256 {
1259 FT_UInt i;
1260
1261
1262 outline = &loader->gloader->base.outline;
1263
1264 /* make room for phantom points */
1266 outline->n_points + 4,
1267 0 );
1268 if ( error )
1269 return error;
1270
1271 outline->points[outline->n_points ] = loader->pp1;
1272 outline->points[outline->n_points + 1] = loader->pp2;
1273 outline->points[outline->n_points + 2] = loader->pp3;
1274 outline->points[outline->n_points + 3] = loader->pp4;
1275
1276 outline->tags[outline->n_points ] = 0;
1277 outline->tags[outline->n_points + 1] = 0;
1278 outline->tags[outline->n_points + 2] = 0;
1279 outline->tags[outline->n_points + 3] = 0;
1280
1281#ifdef TT_USE_BYTECODE_INTERPRETER
1282
1283 {
1284 FT_Stream stream = loader->stream;
1285 FT_UShort n_ins, max_ins;
1286 FT_ULong tmp;
1287
1288
1289 /* TT_Load_Composite_Glyph only gives us the offset of instructions */
1290 /* so we read them here */
1291 if ( FT_STREAM_SEEK( loader->ins_pos ) ||
1292 FT_READ_USHORT( n_ins ) )
1293 return error;
1294
1295 FT_TRACE5(( " Instructions size = %d\n", n_ins ));
1296
1297 /* check it */
1298 max_ins = loader->face->max_profile.maxSizeOfInstructions;
1299 if ( n_ins > max_ins )
1300 {
1301 /* don't trust `maxSizeOfInstructions'; */
1302 /* only do a rough safety check */
1303 if ( (FT_Int)n_ins > loader->byte_len )
1304 {
1305 FT_TRACE1(( "TT_Process_Composite_Glyph:"
1306 " too many instructions (%d) for glyph with length %d\n",
1307 n_ins, loader->byte_len ));
1308 return FT_THROW( Too_Many_Hints );
1309 }
1310
1311 tmp = loader->exec->glyphSize;
1312 error = Update_Max( loader->exec->memory,
1313 &tmp,
1314 sizeof ( FT_Byte ),
1315 (void*)&loader->exec->glyphIns,
1316 n_ins );
1317
1318 loader->exec->glyphSize = (FT_UShort)tmp;
1319 if ( error )
1320 return error;
1321 }
1322 else if ( n_ins == 0 )
1323 return FT_Err_Ok;
1324
1325 if ( FT_STREAM_READ( loader->exec->glyphIns, n_ins ) )
1326 return error;
1327
1328 loader->glyph->control_data = loader->exec->glyphIns;
1329 loader->glyph->control_len = n_ins;
1330 }
1331
1332#endif
1333
1334 tt_prepare_zone( &loader->zone, &loader->gloader->base,
1335 start_point, start_contour );
1336
1337 /* Some points are likely touched during execution of */
1338 /* instructions on components. So let's untouch them. */
1339 for ( i = 0; i < loader->zone.n_points; i++ )
1340 loader->zone.tags[i] &= ~FT_CURVE_TAG_TOUCH_BOTH;
1341
1342 loader->zone.n_points += 4;
1343
1344 return TT_Hint_Glyph( loader, 1 );
1345 }
#define FT_CURVE_TAG_TOUCH_BOTH
Definition: ftimage.h:462
#define FT_READ_USHORT(var)
Definition: ftstream.h:309
#define FT_STREAM_READ(buffer, count)
Definition: ftstream.h:497
void * control_data
Definition: freetype.h:1932
FT_Memory memory
Definition: ttinterp.h:153
FT_UInt glyphSize
Definition: ttinterp.h:192
TT_MaxProfile max_profile
Definition: tttypes.h:1404
FT_UShort n_points
Definition: tttypes.h:1604
FT_Byte * tags
Definition: tttypes.h:1611
FT_UShort maxSizeOfInstructions
Definition: tttables.h:581
static void tt_prepare_zone(TT_GlyphZone zone, FT_GlyphLoad load, FT_UInt start_point, FT_UInt start_contour)
Definition: ttgload.c:753
static FT_Error TT_Hint_Glyph(TT_Loader loader, FT_Bool is_composite)
Definition: ttgload.c:781

Referenced by load_truetype_glyph().

◆ TT_Process_Simple_Glyph()

static FT_Error TT_Process_Simple_Glyph ( TT_Loader  loader)
static

Definition at line 910 of file ttgload.c.

911 {
912 FT_GlyphLoader gloader = loader->gloader;
915 FT_Int n_points;
916
917
918 outline = &gloader->current.outline;
919 n_points = outline->n_points;
920
921 /* set phantom points */
922
923 outline->points[n_points ] = loader->pp1;
924 outline->points[n_points + 1] = loader->pp2;
925 outline->points[n_points + 2] = loader->pp3;
926 outline->points[n_points + 3] = loader->pp4;
927
928 outline->tags[n_points ] = 0;
929 outline->tags[n_points + 1] = 0;
930 outline->tags[n_points + 2] = 0;
931 outline->tags[n_points + 3] = 0;
932
933 n_points += 4;
934
935#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
936
937 if ( FT_IS_NAMED_INSTANCE( FT_FACE( loader->face ) ) ||
938 FT_IS_VARIATION( FT_FACE( loader->face ) ) )
939 {
940 /* Deltas apply to the unscaled data. */
941 error = TT_Vary_Apply_Glyph_Deltas( loader->face,
942 loader->glyph_index,
943 outline,
944 (FT_UInt)n_points );
945
946 /* recalculate linear horizontal and vertical advances */
947 /* if we don't have HVAR and VVAR, respectively */
948 if ( !( loader->face->variation_support & TT_FACE_FLAG_VAR_HADVANCE ) )
949 loader->linear = outline->points[n_points - 3].x -
950 outline->points[n_points - 4].x;
951 if ( !( loader->face->variation_support & TT_FACE_FLAG_VAR_VADVANCE ) )
952 loader->vadvance = outline->points[n_points - 1].x -
953 outline->points[n_points - 2].x;
954
955 if ( error )
956 return error;
957 }
958
959#endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */
960
961 if ( IS_HINTED( loader->load_flags ) )
962 {
963 tt_prepare_zone( &loader->zone, &gloader->current, 0, 0 );
964
965 FT_ARRAY_COPY( loader->zone.orus, loader->zone.cur,
966 loader->zone.n_points + 4 );
967 }
968
969 {
970#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
971 TT_Face face = loader->face;
973
974 FT_String* family = face->root.family_name;
975 FT_UInt ppem = loader->size->metrics->x_ppem;
976 FT_String* style = face->root.style_name;
977 FT_UInt x_scale_factor = 1000;
978#endif
979
980 FT_Vector* vec = outline->points;
981 FT_Vector* limit = outline->points + n_points;
982
983 FT_Fixed x_scale = 0; /* pacify compiler */
984 FT_Fixed y_scale = 0;
985
986 FT_Bool do_scale = FALSE;
987
988
989#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
990
991 if ( driver->interpreter_version == TT_INTERPRETER_VERSION_38 )
992 {
993 /* scale, but only if enabled and only if TT hinting is being used */
994 if ( IS_HINTED( loader->load_flags ) )
995 x_scale_factor = sph_test_tweak_x_scaling( face,
996 family,
997 ppem,
998 style,
999 loader->glyph_index );
1000 /* scale the glyph */
1001 if ( ( loader->load_flags & FT_LOAD_NO_SCALE ) == 0 ||
1002 x_scale_factor != 1000 )
1003 {
1004 x_scale = FT_MulDiv( loader->size->metrics->x_scale,
1005 (FT_Long)x_scale_factor, 1000 );
1006 y_scale = loader->size->metrics->y_scale;
1007
1008 /* compensate for any scaling by de/emboldening; */
1009 /* the amount was determined via experimentation */
1010 if ( x_scale_factor != 1000 && ppem > 11 )
1012 FT_MulFix( 1280 * ppem,
1013 1000 - x_scale_factor ),
1014 0 );
1015 do_scale = TRUE;
1016 }
1017 }
1018 else
1019
1020#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
1021
1022 {
1023 /* scale the glyph */
1024 if ( ( loader->load_flags & FT_LOAD_NO_SCALE ) == 0 )
1025 {
1026 x_scale = loader->size->metrics->x_scale;
1027 y_scale = loader->size->metrics->y_scale;
1028
1029 do_scale = TRUE;
1030 }
1031 }
1032
1033 if ( do_scale )
1034 {
1035 for ( ; vec < limit; vec++ )
1036 {
1037 vec->x = FT_MulFix( vec->x, x_scale );
1038 vec->y = FT_MulFix( vec->y, y_scale );
1039 }
1040 }
1041
1042#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
1043 /* if we have a HVAR table, `pp1' and/or `pp2' are already adjusted */
1044 if ( !( loader->face->variation_support & TT_FACE_FLAG_VAR_HADVANCE ) ||
1045 !IS_HINTED( loader->load_flags ) )
1046#endif
1047 {
1048 loader->pp1 = outline->points[n_points - 4];
1049 loader->pp2 = outline->points[n_points - 3];
1050 }
1051
1052#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
1053 /* if we have a VVAR table, `pp3' and/or `pp4' are already adjusted */
1054 if ( !( loader->face->variation_support & TT_FACE_FLAG_VAR_VADVANCE ) ||
1055 !IS_HINTED( loader->load_flags ) )
1056#endif
1057 {
1058 loader->pp3 = outline->points[n_points - 2];
1059 loader->pp4 = outline->points[n_points - 1];
1060 }
1061 }
1062
1063 if ( IS_HINTED( loader->load_flags ) )
1064 {
1065 loader->zone.n_points += 4;
1066
1067 error = TT_Hint_Glyph( loader, 0 );
1068 }
1069
1070 return error;
1071 }
Arabic default style
Definition: afstyles.h:94
FT_MulDiv(FT_Long a, FT_Long b, FT_Long c)
Definition: ftcalc.c:416
char FT_String
Definition: fttypes.h:187
FT_UShort x_ppem
Definition: freetype.h:1640
FT_Vector * orus
Definition: tttypes.h:1609
FT_Vector * cur
Definition: tttypes.h:1608

Referenced by load_truetype_glyph().