ReactOS 0.4.15-dev-7942-gd23573b
opentype.c File Reference
#include <stdarg.h>
#include <stdlib.h>
#include "windef.h"
#include "winbase.h"
#include "wingdi.h"
#include "winuser.h"
#include "winnls.h"
#include "usp10.h"
#include "winternl.h"
#include "usp10_internal.h"
#include "wine/debug.h"
#include "wine/heap.h"
Include dependency graph for opentype.c:

Go to the source code of this file.

Classes

struct  CMAP_EncodingRecord
 
struct  CMAP_Header
 
struct  CMAP_SegmentedCoverage_group
 
struct  CMAP_SegmentedCoverage
 
struct  GDEF_Header
 
struct  OT_ClassDefFormat1
 
struct  OT_ClassRangeRecord
 
struct  OT_ClassDefFormat2
 
struct  GSUB_Header
 
struct  OT_ScriptRecord
 
struct  OT_ScriptList
 
struct  OT_LangSysRecord
 
struct  OT_Script
 
struct  OT_LangSys
 
struct  OT_FeatureRecord
 
struct  OT_FeatureList
 
struct  OT_Feature
 
struct  OT_LookupList
 
struct  OT_LookupTable
 
struct  OT_CoverageFormat1
 
struct  OT_RangeRecord
 
struct  OT_CoverageFormat2
 
struct  GSUB_SingleSubstFormat1
 
struct  GSUB_SingleSubstFormat2
 
struct  GSUB_MultipleSubstFormat1
 
struct  GSUB_Sequence
 
struct  GSUB_LigatureSubstFormat1
 
struct  GSUB_LigatureSet
 
struct  GSUB_Ligature
 
struct  GSUB_SubstLookupRecord
 
struct  GSUB_ContextSubstFormat1
 
struct  GSUB_SubRuleSet
 
struct  GSUB_SubRule_1
 
struct  GSUB_SubRule_2
 
struct  GSUB_ContextSubstFormat2
 
struct  GSUB_SubClassSet
 
struct  GSUB_SubClassRule_1
 
struct  GSUB_SubClassRule_2
 
struct  GSUB_ChainContextSubstFormat1
 
struct  GSUB_ChainContextSubstFormat2
 
struct  GSUB_ChainSubClassSet
 
struct  GSUB_ChainSubClassRule_1
 
struct  GSUB_ChainSubClassRule_2
 
struct  GSUB_ChainSubClassRule_3
 
struct  GSUB_ChainSubClassRule_4
 
struct  GSUB_ChainContextSubstFormat3_1
 
struct  GSUB_ChainContextSubstFormat3_2
 
struct  GSUB_ChainContextSubstFormat3_3
 
struct  GSUB_ChainContextSubstFormat3_4
 
struct  GSUB_AlternateSubstFormat1
 
struct  GSUB_AlternateSet
 
struct  GSUB_ExtensionPosFormat1
 
struct  GPOS_Header
 
struct  OT_DeviceTable
 
struct  GPOS_AnchorFormat1
 
struct  GPOS_AnchorFormat2
 
struct  GPOS_AnchorFormat3
 
struct  GPOS_ValueRecord
 
struct  GPOS_SinglePosFormat1
 
struct  GPOS_SinglePosFormat2
 
struct  GPOS_PairPosFormat1
 
struct  GPOS_PairPosFormat2
 
struct  GPOS_PairValueRecord
 
struct  GPOS_PairSet
 
struct  GPOS_EntryExitRecord
 
struct  GPOS_CursivePosFormat1
 
struct  GPOS_MarkBasePosFormat1
 
struct  GPOS_BaseRecord
 
struct  GPOS_BaseArray
 
struct  GPOS_MarkRecord
 
struct  GPOS_MarkArray
 
struct  GPOS_MarkLigPosFormat1
 
struct  GPOS_LigatureArray
 
struct  GPOS_ComponentRecord
 
struct  GPOS_LigatureAttach
 
struct  GPOS_MarkMarkPosFormat1
 
struct  GPOS_Mark2Record
 
struct  GPOS_Mark2Array
 
struct  GPOS_PosLookupRecord
 
struct  GPOS_ContextPosFormat2
 
struct  GPOS_PosClassSet
 
struct  GPOS_PosClassRule_1
 
struct  GPOS_PosClassRule_2
 
struct  GPOS_ChainContextPosFormat3_1
 
struct  GPOS_ChainContextPosFormat3_2
 
struct  GPOS_ChainContextPosFormat3_3
 
struct  GPOS_ChainContextPosFormat3_4
 
struct  GPOS_ExtensionPosFormat1
 

Macros

#define GET_BE_WORD(x)   RtlUshortByteSwap(x)
 
#define GET_BE_DWORD(x)   RtlUlongByteSwap(x)
 
#define round(x)   (((x) < 0) ? (int)((x) - 0.5) : (int)((x) + 0.5))
 
#define CMAP_TAG   MS_MAKE_TAG('c', 'm', 'a', 'p')
 

Enumerations

enum  gpos_lookup_type {
  GPOS_LOOKUP_ADJUST_SINGLE = 0x1 , GPOS_LOOKUP_ADJUST_PAIR = 0x2 , GPOS_LOOKUP_ATTACH_CURSIVE = 0x3 , GPOS_LOOKUP_ATTACH_MARK_TO_BASE = 0x4 ,
  GPOS_LOOKUP_ATTACH_MARK_TO_LIGATURE = 0x5 , GPOS_LOOKUP_ATTACH_MARK_TO_MARK = 0x6 , GPOS_LOOKUP_POSITION_CONTEXT = 0x7 , GPOS_LOOKUP_POSITION_CONTEXT_CHAINED = 0x8 ,
  GPOS_LOOKUP_POSITION_EXTENSION = 0x9
}
 
enum  gsub_lookup_type {
  GSUB_LOOKUP_SINGLE = 0x1 , GSUB_LOOKUP_MULTIPLE = 0x2 , GSUB_LOOKUP_ALTERNATE = 0x3 , GSUB_LOOKUP_LIGATURE = 0x4 ,
  GSUB_LOOKUP_CONTEXT = 0x5 , GSUB_LOOKUP_CONTEXT_CHAINED = 0x6 , GSUB_LOOKUP_EXTENSION = 0x7 , GSUB_LOOKUP_CONTEXT_CHAINED_REVERSE = 0x8
}
 
enum  { BaseGlyph =1 , LigatureGlyph , MarkGlyph , ComponentGlyph }
 

Functions

 WINE_DEFAULT_DEBUG_CHANNEL (uniscribe)
 
static VOIDload_CMAP_format12_table (HDC hdc, ScriptCache *psc)
 
static int __cdecl compare_group (const void *a, const void *b)
 
DWORD OpenType_CMAP_GetGlyphIndex (HDC hdc, ScriptCache *psc, DWORD utf32c, WORD *glyph_index, DWORD flags)
 
static WORD OT_get_glyph_class (const void *table, WORD glyph)
 
void OpenType_GDEF_UpdateGlyphProps (ScriptCache *psc, const WORD *pwGlyphs, const WORD cGlyphs, WORD *pwLogClust, const WORD cChars, SCRIPT_GLYPHPROP *pGlyphProp)
 
static INT GSUB_apply_lookup (const OT_LookupList *lookup, INT lookup_index, WORD *glyphs, INT glyph_index, INT write_dir, INT *glyph_count)
 
static int GSUB_is_glyph_covered (const void *table, unsigned int glyph)
 
static const BYTEGSUB_get_subtable (const OT_LookupTable *look, int index)
 
static INT GSUB_apply_SingleSubst (const OT_LookupTable *look, WORD *glyphs, INT glyph_index, INT write_dir, INT *glyph_count)
 
static INT GSUB_apply_MultipleSubst (const OT_LookupTable *look, WORD *glyphs, INT glyph_index, INT write_dir, INT *glyph_count)
 
static INT GSUB_apply_AlternateSubst (const OT_LookupTable *look, WORD *glyphs, INT glyph_index, INT write_dir, INT *glyph_count)
 
static INT GSUB_apply_LigatureSubst (const OT_LookupTable *look, WORD *glyphs, INT glyph_index, INT write_dir, INT *glyph_count)
 
static INT GSUB_apply_ContextSubst (const OT_LookupList *lookup, const OT_LookupTable *look, WORD *glyphs, INT glyph_index, INT write_dir, INT *glyph_count)
 
static INT GSUB_apply_ChainContextSubst (const OT_LookupList *lookup, const OT_LookupTable *look, WORD *glyphs, INT glyph_index, INT write_dir, INT *glyph_count)
 
int OpenType_apply_GSUB_lookup (const void *table, unsigned int lookup_index, WORD *glyphs, unsigned int glyph_index, int write_dir, int *glyph_count)
 
static unsigned int GPOS_apply_lookup (const ScriptCache *script_cache, const OUTLINETEXTMETRICW *otm, const LOGFONTW *logfont, const SCRIPT_ANALYSIS *analysis, int *advance, const OT_LookupList *lookup, unsigned int lookup_index, const WORD *glyphs, unsigned int glyph_index, unsigned int glyph_count, GOFFSET *goffset)
 
static INT GPOS_get_device_table_value (const OT_DeviceTable *DeviceTable, WORD ppem)
 
static void GPOS_get_anchor_values (const void *table, POINT *pt, WORD ppem)
 
static void GPOS_convert_design_units_to_device (const OUTLINETEXTMETRICW *otm, const LOGFONTW *logfont, int desX, int desY, double *devX, double *devY)
 
static INT GPOS_get_value_record (WORD ValueFormat, const WORD data[], GPOS_ValueRecord *record)
 
static void GPOS_get_value_record_offsets (const BYTE *head, GPOS_ValueRecord *ValueRecord, WORD ValueFormat, unsigned int ppem, POINT *ptPlacement, POINT *ptAdvance)
 
static const BYTEGPOS_get_subtable (const OT_LookupTable *look, int index)
 
static void GPOS_apply_SingleAdjustment (const OT_LookupTable *look, const SCRIPT_ANALYSIS *analysis, const WORD *glyphs, unsigned int glyph_index, unsigned int glyph_count, unsigned int ppem, POINT *adjust, POINT *advance)
 
static void apply_pair_value (const void *pos_table, WORD val_fmt1, WORD val_fmt2, const WORD *pair, INT ppem, POINT *adjust, POINT *advance)
 
static int GPOS_apply_PairAdjustment (const OT_LookupTable *look, const SCRIPT_ANALYSIS *analysis, const WORD *glyphs, unsigned int glyph_index, unsigned int glyph_count, unsigned int ppem, POINT *adjust, POINT *advance)
 
static void GPOS_apply_CursiveAttachment (const OT_LookupTable *look, const SCRIPT_ANALYSIS *analysis, const WORD *glyphs, unsigned int glyph_index, unsigned int glyph_count, unsigned int ppem, POINT *pt)
 
static int GPOS_apply_MarkToBase (const ScriptCache *script_cache, const OT_LookupTable *look, const SCRIPT_ANALYSIS *analysis, const WORD *glyphs, unsigned int glyph_index, unsigned int glyph_count, unsigned int ppem, POINT *pt)
 
static void GPOS_apply_MarkToLigature (const OT_LookupTable *look, const SCRIPT_ANALYSIS *analysis, const WORD *glyphs, unsigned int glyph_index, unsigned int glyph_count, unsigned int ppem, POINT *pt)
 
static BOOL GPOS_apply_MarkToMark (const OT_LookupTable *look, const SCRIPT_ANALYSIS *analysis, const WORD *glyphs, unsigned int glyph_index, unsigned int glyph_count, unsigned int ppem, POINT *pt)
 
static unsigned int GPOS_apply_ContextPos (const ScriptCache *script_cache, const OUTLINETEXTMETRICW *otm, const LOGFONTW *logfont, const SCRIPT_ANALYSIS *analysis, int *advance, const OT_LookupList *lookup, const OT_LookupTable *look, const WORD *glyphs, unsigned int glyph_index, unsigned int glyph_count, GOFFSET *goffset)
 
static unsigned int GPOS_apply_ChainContextPos (const ScriptCache *script_cache, const OUTLINETEXTMETRICW *otm, const LOGFONTW *logfont, const SCRIPT_ANALYSIS *analysis, int *advance, const OT_LookupList *lookup, const OT_LookupTable *look, const WORD *glyphs, unsigned int glyph_index, unsigned int glyph_count, GOFFSET *goffset)
 
unsigned int OpenType_apply_GPOS_lookup (const ScriptCache *script_cache, const OUTLINETEXTMETRICW *otm, const LOGFONTW *logfont, const SCRIPT_ANALYSIS *analysis, int *advance, unsigned int lookup_index, const WORD *glyphs, unsigned int glyph_index, unsigned int glyph_count, GOFFSET *goffset)
 
static LoadedScriptusp10_script_cache_add_script (ScriptCache *script_cache, OPENTYPE_TAG tag)
 
static LoadedScriptusp10_script_cache_get_script (ScriptCache *script_cache, OPENTYPE_TAG tag)
 
static void usp10_script_cache_add_script_list (ScriptCache *script_cache, enum usp10_script_table table, const OT_ScriptList *list)
 
static void _initialize_script_cache (ScriptCache *script_cache)
 
HRESULT OpenType_GetFontScriptTags (ScriptCache *psc, OPENTYPE_TAG searchingFor, int cMaxTags, OPENTYPE_TAG *pScriptTags, int *pcTags)
 
static LoadedLanguageusp10_script_add_language (LoadedScript *script, OPENTYPE_TAG tag)
 
static LoadedLanguageusp10_script_get_language (LoadedScript *script, OPENTYPE_TAG tag)
 
static void usp10_script_add_language_list (LoadedScript *script, enum usp10_language_table table, const OT_Script *list)
 
static void _initialize_language_cache (LoadedScript *script)
 
HRESULT OpenType_GetFontLanguageTags (ScriptCache *psc, OPENTYPE_TAG script_tag, OPENTYPE_TAG searchingFor, int cMaxTags, OPENTYPE_TAG *pLanguageTags, int *pcTags)
 
static void usp10_language_add_feature_list (LoadedLanguage *language, char table_type, const OT_LangSys *lang, const OT_FeatureList *feature_list)
 
static void _initialize_feature_cache (ScriptCache *psc, LoadedLanguage *language)
 
HRESULT OpenType_GetFontFeatureTags (ScriptCache *psc, OPENTYPE_TAG script_tag, OPENTYPE_TAG language_tag, BOOL filtered, OPENTYPE_TAG searchingFor, char tableType, int cMaxTags, OPENTYPE_TAG *pFeatureTags, int *pcTags, LoadedFeature **feature)
 

Macro Definition Documentation

◆ CMAP_TAG

#define CMAP_TAG   MS_MAKE_TAG('c', 'm', 'a', 'p')

Definition at line 50 of file opentype.c.

◆ GET_BE_DWORD

#define GET_BE_DWORD (   x)    RtlUlongByteSwap(x)

Definition at line 44 of file opentype.c.

◆ GET_BE_WORD

#define GET_BE_WORD (   x)    RtlUshortByteSwap(x)

Definition at line 43 of file opentype.c.

◆ round

#define round (   x)    (((x) < 0) ? (int)((x) - 0.5) : (int)((x) + 0.5))

Definition at line 47 of file opentype.c.

Enumeration Type Documentation

◆ anonymous enum

anonymous enum
Enumerator
BaseGlyph 
LigatureGlyph 
MarkGlyph 
ComponentGlyph 

Definition at line 105 of file opentype.c.

@ LigatureGlyph
Definition: opentype.c:105
@ ComponentGlyph
Definition: opentype.c:105
@ BaseGlyph
Definition: opentype.c:105
@ MarkGlyph
Definition: opentype.c:105

◆ gpos_lookup_type

Enumerator
GPOS_LOOKUP_ADJUST_SINGLE 
GPOS_LOOKUP_ADJUST_PAIR 
GPOS_LOOKUP_ATTACH_CURSIVE 
GPOS_LOOKUP_ATTACH_MARK_TO_BASE 
GPOS_LOOKUP_ATTACH_MARK_TO_LIGATURE 
GPOS_LOOKUP_ATTACH_MARK_TO_MARK 
GPOS_LOOKUP_POSITION_CONTEXT 
GPOS_LOOKUP_POSITION_CONTEXT_CHAINED 
GPOS_LOOKUP_POSITION_EXTENSION 

Definition at line 52 of file opentype.c.

53{
63};
@ GPOS_LOOKUP_POSITION_CONTEXT_CHAINED
Definition: opentype.c:61
@ GPOS_LOOKUP_ATTACH_MARK_TO_LIGATURE
Definition: opentype.c:58
@ GPOS_LOOKUP_ADJUST_SINGLE
Definition: opentype.c:54
@ GPOS_LOOKUP_ADJUST_PAIR
Definition: opentype.c:55
@ GPOS_LOOKUP_ATTACH_MARK_TO_BASE
Definition: opentype.c:57
@ GPOS_LOOKUP_POSITION_EXTENSION
Definition: opentype.c:62
@ GPOS_LOOKUP_ATTACH_MARK_TO_MARK
Definition: opentype.c:59
@ GPOS_LOOKUP_ATTACH_CURSIVE
Definition: opentype.c:56
@ GPOS_LOOKUP_POSITION_CONTEXT
Definition: opentype.c:60

◆ gsub_lookup_type

Enumerator
GSUB_LOOKUP_SINGLE 
GSUB_LOOKUP_MULTIPLE 
GSUB_LOOKUP_ALTERNATE 
GSUB_LOOKUP_LIGATURE 
GSUB_LOOKUP_CONTEXT 
GSUB_LOOKUP_CONTEXT_CHAINED 
GSUB_LOOKUP_EXTENSION 
GSUB_LOOKUP_CONTEXT_CHAINED_REVERSE 

Definition at line 65 of file opentype.c.

66{
75};
@ GSUB_LOOKUP_CONTEXT_CHAINED_REVERSE
Definition: opentype.c:74
@ GSUB_LOOKUP_LIGATURE
Definition: opentype.c:70
@ GSUB_LOOKUP_SINGLE
Definition: opentype.c:67
@ GSUB_LOOKUP_MULTIPLE
Definition: opentype.c:68
@ GSUB_LOOKUP_EXTENSION
Definition: opentype.c:73
@ GSUB_LOOKUP_CONTEXT_CHAINED
Definition: opentype.c:72
@ GSUB_LOOKUP_CONTEXT
Definition: opentype.c:71
@ GSUB_LOOKUP_ALTERNATE
Definition: opentype.c:69

Function Documentation

◆ _initialize_feature_cache()

static void _initialize_feature_cache ( ScriptCache psc,
LoadedLanguage language 
)
static

Definition at line 2847 of file opentype.c.

2848{
2849 const GSUB_Header *gsub_header = psc->GSUB_Table;
2850 const GPOS_Header *gpos_header = psc->GPOS_Table;
2851 const OT_FeatureList *feature_list;
2852 const OT_LangSys *lang;
2853
2854 if (language->features_initialized)
2855 return;
2856
2857 if ((lang = language->table[USP10_LANGUAGE_TABLE_GSUB]))
2858 {
2859 feature_list = (const OT_FeatureList *)((const BYTE *)gsub_header + GET_BE_WORD(gsub_header->FeatureList));
2861 }
2862
2863 if ((lang = language->table[USP10_LANGUAGE_TABLE_GPOS]))
2864 {
2865 feature_list = (const OT_FeatureList *)((const BYTE *)gpos_header + GET_BE_WORD(gpos_header->FeatureList));
2867 }
2868
2869 language->features_initialized = TRUE;
2870}
#define TRUE
Definition: types.h:120
static SCRIPT_CACHE * psc
Definition: usp10.c:64
static void usp10_language_add_feature_list(LoadedLanguage *language, char table_type, const OT_LangSys *lang, const OT_FeatureList *feature_list)
Definition: opentype.c:2813
#define GET_BE_WORD(x)
Definition: opentype.c:43
WORD FeatureList
Definition: opentype.c:397
WORD FeatureList
Definition: opentype.c:139
const void * table[USP10_LANGUAGE_TABLE_COUNT]
#define FEATURE_GSUB_TABLE
@ USP10_LANGUAGE_TABLE_GSUB
@ USP10_LANGUAGE_TABLE_GPOS
#define FEATURE_GPOS_TABLE
static const WCHAR lang[]
Definition: wbemdisp.c:287
unsigned char BYTE
Definition: xxhash.c:193

Referenced by OpenType_GetFontFeatureTags().

◆ _initialize_language_cache()

static void _initialize_language_cache ( LoadedScript script)
static

Definition at line 2746 of file opentype.c.

2747{
2748 const OT_Script *list;
2749
2750 if (script->languages_initialized)
2751 return;
2752
2753 if ((list = script->table[USP10_SCRIPT_TABLE_GSUB]))
2755 if ((list = script->table[USP10_SCRIPT_TABLE_GPOS]))
2757
2758 script->languages_initialized = TRUE;
2759}
Definition: list.h:37
script
Definition: msipriv.h:383
static void usp10_script_add_language_list(LoadedScript *script, enum usp10_language_table table, const OT_Script *list)
Definition: opentype.c:2708
#define list
Definition: rosglue.h:35
@ USP10_SCRIPT_TABLE_GSUB
@ USP10_SCRIPT_TABLE_GPOS

Referenced by OpenType_GetFontFeatureTags(), and OpenType_GetFontLanguageTags().

◆ _initialize_script_cache()

static void _initialize_script_cache ( ScriptCache script_cache)
static

Definition at line 2628 of file opentype.c.

2629{
2630 const GPOS_Header *gpos_header;
2631 const GSUB_Header *gsub_header;
2632
2633 if (script_cache->scripts_initialized)
2634 return;
2635
2636 if ((gsub_header = script_cache->GSUB_Table))
2638 (const OT_ScriptList *)((const BYTE *)gsub_header + GET_BE_WORD(gsub_header->ScriptList)));
2639
2640 if ((gpos_header = script_cache->GPOS_Table))
2642 (const OT_ScriptList *)((const BYTE *)gpos_header + GET_BE_WORD(gpos_header->ScriptList)));
2643
2644 script_cache->scripts_initialized = TRUE;
2645}
static void usp10_script_cache_add_script_list(ScriptCache *script_cache, enum usp10_script_table table, const OT_ScriptList *list)
Definition: opentype.c:2598
WORD ScriptList
Definition: opentype.c:396
WORD ScriptList
Definition: opentype.c:138
void * GPOS_Table
BOOL scripts_initialized
void * GSUB_Table

Referenced by OpenType_GetFontFeatureTags(), OpenType_GetFontLanguageTags(), and OpenType_GetFontScriptTags().

◆ apply_pair_value()

static void apply_pair_value ( const void pos_table,
WORD  val_fmt1,
WORD  val_fmt2,
const WORD pair,
INT  ppem,
POINT adjust,
POINT advance 
)
static

Definition at line 1746 of file opentype.c.

1748{
1749 GPOS_ValueRecord val_rec1 = {0,0,0,0,0,0,0,0};
1750 GPOS_ValueRecord val_rec2 = {0,0,0,0,0,0,0,0};
1751 INT size;
1752
1753 size = GPOS_get_value_record( val_fmt1, pair, &val_rec1 );
1754 GPOS_get_value_record( val_fmt2, pair + size, &val_rec2 );
1755
1756 if (val_fmt1)
1757 {
1758 GPOS_get_value_record_offsets( pos_table, &val_rec1, val_fmt1, ppem, adjust, advance );
1759 TRACE( "Glyph 1 resulting cumulative offset is %s design units\n", wine_dbgstr_point(&adjust[0]) );
1760 TRACE( "Glyph 1 resulting cumulative advance is %s design units\n", wine_dbgstr_point(&advance[0]) );
1761 }
1762 if (val_fmt2)
1763 {
1764 GPOS_get_value_record_offsets( pos_table, &val_rec2, val_fmt2, ppem, adjust + 1, advance + 1 );
1765 TRACE( "Glyph 2 resulting cumulative offset is %s design units\n", wine_dbgstr_point(&adjust[1]) );
1766 TRACE( "Glyph 2 resulting cumulative advance is %s design units\n", wine_dbgstr_point(&advance[1]) );
1767 }
1768}
_STLP_MOVE_TO_STD_NAMESPACE void _STLP_CALL advance(_InputIterator &__i, _Distance __n)
static const char * wine_dbgstr_point(const POINT *ppt)
Definition: atltest.h:138
GLsizeiptr size
Definition: glext.h:5919
static INT GPOS_get_value_record(WORD ValueFormat, const WORD data[], GPOS_ValueRecord *record)
Definition: opentype.c:1648
static void GPOS_get_value_record_offsets(const BYTE *head, GPOS_ValueRecord *ValueRecord, WORD ValueFormat, unsigned int ppem, POINT *ptPlacement, POINT *ptAdvance)
Definition: opentype.c:1662
#define TRACE(s)
Definition: solgame.cpp:4
Definition: _pair.h:47
int32_t INT
Definition: typedefs.h:58

Referenced by GPOS_apply_PairAdjustment().

◆ compare_group()

static int __cdecl compare_group ( const void a,
const void b 
)
static

Definition at line 661 of file opentype.c.

662{
663 const DWORD *chr = a;
665
666 if (*chr < GET_BE_DWORD(group->startCharCode))
667 return -1;
668 if (*chr > GET_BE_DWORD(group->endCharCode))
669 return 1;
670 return 0;
671}
unsigned long DWORD
Definition: ntddk_ex.h:95
GLboolean GLuint group
Definition: glext.h:11120
#define a
Definition: ke_i.h:78
#define b
Definition: ke_i.h:79
#define GET_BE_DWORD(x)
Definition: opentype.c:44

Referenced by OpenType_CMAP_GetGlyphIndex().

◆ GPOS_apply_ChainContextPos()

static unsigned int GPOS_apply_ChainContextPos ( const ScriptCache script_cache,
const OUTLINETEXTMETRICW otm,
const LOGFONTW logfont,
const SCRIPT_ANALYSIS analysis,
int advance,
const OT_LookupList lookup,
const OT_LookupTable look,
const WORD glyphs,
unsigned int  glyph_index,
unsigned int  glyph_count,
GOFFSET goffset 
)
static

Definition at line 2261 of file opentype.c.

2265{
2266 int j;
2267 int write_dir = (analysis->fRTL && !analysis->fLogicalOrder) ? -1 : 1;
2268
2269 TRACE("Chaining Contextual Positioning Subtable\n");
2270
2271 for (j = 0; j < GET_BE_WORD(look->SubTableCount); j++)
2272 {
2273 int offset;
2275 int dirLookahead = write_dir;
2276 int dirBacktrack = -1 * write_dir;
2277
2278 if (GET_BE_WORD(backtrack->PosFormat) == 1)
2279 {
2280 static int once;
2281 if (!once++)
2282 FIXME(" TODO: subtype 1 (Simple Chaining Context Glyph Positioning)\n");
2283 continue;
2284 }
2285 else if (GET_BE_WORD(backtrack->PosFormat) == 2)
2286 {
2287 static int once;
2288 if (!once++)
2289 FIXME(" TODO: subtype 2 (Class-based Chaining Context Glyph Positioning)\n");
2290 continue;
2291 }
2292 else if (GET_BE_WORD(backtrack->PosFormat) == 3)
2293 {
2294 WORD backtrack_count, input_count, lookahead_count, positioning_count;
2295 int k;
2297 const GPOS_ChainContextPosFormat3_3 *lookahead;
2298 const GPOS_ChainContextPosFormat3_4 *positioning;
2299
2300 TRACE(" subtype 3 (Coverage-based Chaining Context Glyph Positioning)\n");
2301
2302 backtrack_count = GET_BE_WORD(backtrack->BacktrackGlyphCount);
2303 k = glyph_index + dirBacktrack * backtrack_count;
2304 if (k < 0 || k >= glyph_count)
2305 continue;
2306
2307 input = (const GPOS_ChainContextPosFormat3_2 *)&backtrack->Coverage[backtrack_count];
2308 input_count = GET_BE_WORD(input->InputGlyphCount);
2309 k = glyph_index + write_dir * (input_count - 1);
2310 if (k < 0 || k >= glyph_count)
2311 continue;
2312
2313 lookahead = (const GPOS_ChainContextPosFormat3_3 *)&input->Coverage[input_count];
2314 lookahead_count = GET_BE_WORD(lookahead->LookaheadGlyphCount);
2315 k = glyph_index + dirLookahead * (input_count + lookahead_count - 1);
2316 if (k < 0 || k >= glyph_count)
2317 continue;
2318
2319 positioning = (const GPOS_ChainContextPosFormat3_4 *)&lookahead->Coverage[lookahead_count];
2320
2321 for (k = 0; k < backtrack_count; ++k)
2322 {
2323 offset = GET_BE_WORD(backtrack->Coverage[k]);
2324 if (GSUB_is_glyph_covered((const BYTE *)backtrack + offset,
2325 glyphs[glyph_index + (dirBacktrack * (k + 1))]) == -1)
2326 break;
2327 }
2328 if (k != backtrack_count)
2329 continue;
2330 TRACE("Matched Backtrack\n");
2331
2332 for (k = 0; k < input_count; ++k)
2333 {
2334 offset = GET_BE_WORD(input->Coverage[k]);
2335 if (GSUB_is_glyph_covered((const BYTE *)backtrack + offset,
2336 glyphs[glyph_index + (write_dir * k)]) == -1)
2337 break;
2338 }
2339 if (k != input_count)
2340 continue;
2341 TRACE("Matched IndexGlyphs\n");
2342
2343 for (k = 0; k < lookahead_count; ++k)
2344 {
2345 offset = GET_BE_WORD(lookahead->Coverage[k]);
2346 if (GSUB_is_glyph_covered((const BYTE *)backtrack + offset,
2347 glyphs[glyph_index + (dirLookahead * (input_count + k))]) == -1)
2348 break;
2349 }
2350 if (k != lookahead_count)
2351 continue;
2352 TRACE("Matched LookAhead\n");
2353
2354 if (!(positioning_count = GET_BE_WORD(positioning->PosCount)))
2355 return 1;
2356
2357 for (k = 0; k < positioning_count; ++k)
2358 {
2359 unsigned int lookup_index = GET_BE_WORD(positioning->PosLookupRecord[k].LookupListIndex);
2360 unsigned int sequence_index = GET_BE_WORD(positioning->PosLookupRecord[k].SequenceIndex);
2361 unsigned int g = glyph_index + write_dir * sequence_index;
2362
2363 if (g >= glyph_count)
2364 {
2365 WARN("Skipping invalid sequence index %u (glyph index %u, write dir %d).\n",
2366 sequence_index, glyph_index, write_dir);
2367 continue;
2368 }
2369
2370 TRACE("Position: %u -> %u %u.\n", k, sequence_index, lookup_index);
2371 GPOS_apply_lookup(script_cache, otm, logfont, analysis, advance, lookup, lookup_index,
2372 glyphs, g, glyph_count, goffset);
2373 }
2374 return input_count + lookahead_count;
2375 }
2376 else
2377 FIXME("Unhandled Chaining Contextual Positioning Format %#x.\n", GET_BE_WORD(backtrack->PosFormat));
2378 }
2379 return 1;
2380}
#define FIXME(fmt,...)
Definition: debug.h:111
#define WARN(fmt,...)
Definition: debug.h:112
static ULONG lookup[16]
Definition: vga.c:48
unsigned short WORD
Definition: ntddk_ex.h:93
GLboolean GLboolean g
Definition: glext.h:6204
GLenum GLenum GLenum input
Definition: glext.h:9031
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 GLint GLint j
Definition: glfuncs.h:250
#define for
Definition: utility.h:88
static UINT UINT LPWORD glyphs
Definition: font.c:44
int k
Definition: mpi.c:3369
static int GSUB_is_glyph_covered(const void *table, unsigned int glyph)
Definition: opentype.c:819
static unsigned int GPOS_apply_lookup(const ScriptCache *script_cache, const OUTLINETEXTMETRICW *otm, const LOGFONTW *logfont, const SCRIPT_ANALYSIS *analysis, int *advance, const OT_LookupList *lookup, unsigned int lookup_index, const WORD *glyphs, unsigned int glyph_index, unsigned int glyph_count, GOFFSET *goffset)
Definition: opentype.c:2382
static const BYTE * GPOS_get_subtable(const OT_LookupTable *look, int index)
Definition: opentype.c:1676
GPOS_PosLookupRecord PosLookupRecord[1]
Definition: opentype.c:614
WORD SubTableCount
Definition: opentype.c:195
WORD fLogicalOrder
Definition: usp10.h:144

Referenced by GPOS_apply_lookup().

◆ GPOS_apply_ContextPos()

static unsigned int GPOS_apply_ContextPos ( const ScriptCache script_cache,
const OUTLINETEXTMETRICW otm,
const LOGFONTW logfont,
const SCRIPT_ANALYSIS analysis,
int advance,
const OT_LookupList lookup,
const OT_LookupTable look,
const WORD glyphs,
unsigned int  glyph_index,
unsigned int  glyph_count,
GOFFSET goffset 
)
static

Definition at line 2142 of file opentype.c.

2146{
2147 int j;
2148 int write_dir = (analysis->fRTL && !analysis->fLogicalOrder) ? -1 : 1;
2149
2150 TRACE("Contextual Positioning Subtable\n");
2151
2152 for (j = 0; j < GET_BE_WORD(look->SubTableCount); j++)
2153 {
2155
2156 if (GET_BE_WORD(cpf2->PosFormat) == 1)
2157 {
2158 static int once;
2159 if (!once++)
2160 FIXME(" TODO: subtype 1\n");
2161 continue;
2162 }
2163 else if (GET_BE_WORD(cpf2->PosFormat) == 2)
2164 {
2166 int index;
2167
2168 TRACE("Contextual Positioning Subtable: Format 2\n");
2169
2170 index = GSUB_is_glyph_covered((const BYTE*)cpf2+offset, glyphs[glyph_index]);
2171 TRACE("Coverage index %i\n",index);
2172 if (index != -1)
2173 {
2174 int k, count, class;
2175 const GPOS_PosClassSet *pcs;
2176 const void *glyph_class_table = NULL;
2177
2178 offset = GET_BE_WORD(cpf2->ClassDef);
2179 glyph_class_table = (const BYTE *)cpf2 + offset;
2180
2181 class = OT_get_glyph_class(glyph_class_table,glyphs[glyph_index]);
2182
2183 offset = GET_BE_WORD(cpf2->PosClassSet[class]);
2184 if (offset == 0)
2185 {
2186 TRACE("No class rule table for class %i\n",class);
2187 continue;
2188 }
2189 pcs = (const GPOS_PosClassSet*)((const BYTE*)cpf2+offset);
2191 TRACE("PosClassSet has %i members\n",count);
2192 for (k = 0; k < count; k++)
2193 {
2194 const GPOS_PosClassRule_1 *pr;
2195 const GPOS_PosClassRule_2 *pr_2;
2196 unsigned int g;
2197 int g_count, l;
2198
2200 pr = (const GPOS_PosClassRule_1*)((const BYTE*)pcs+offset);
2201 g_count = GET_BE_WORD(pr->GlyphCount);
2202 TRACE("PosClassRule has %i glyphs classes\n",g_count);
2203
2204 g = glyph_index + write_dir * (g_count - 1);
2205 if (g >= glyph_count)
2206 continue;
2207
2208 for (l = 0; l < g_count-1; l++)
2209 {
2210 int g_class = OT_get_glyph_class(glyph_class_table, glyphs[glyph_index + (write_dir * (l+1))]);
2211 if (g_class != GET_BE_WORD(pr->Class[l])) break;
2212 }
2213
2214 if (l < g_count-1)
2215 {
2216 TRACE("Rule does not match\n");
2217 continue;
2218 }
2219
2220 TRACE("Rule matches\n");
2221 pr_2 = (const GPOS_PosClassRule_2 *)&pr->Class[g_count - 1];
2222
2223 for (l = 0; l < GET_BE_WORD(pr->PosCount); l++)
2224 {
2225 unsigned int lookup_index = GET_BE_WORD(pr_2->PosLookupRecord[l].LookupListIndex);
2226 unsigned int sequence_index = GET_BE_WORD(pr_2->PosLookupRecord[l].SequenceIndex);
2227
2228 g = glyph_index + write_dir * sequence_index;
2229 if (g >= glyph_count)
2230 {
2231 WARN("Invalid sequence index %u (glyph index %u, write dir %d).\n",
2232 sequence_index, glyph_index, write_dir);
2233 continue;
2234 }
2235
2236 TRACE("Position: %u -> %u %u.\n", l, sequence_index, lookup_index);
2237
2238 GPOS_apply_lookup(script_cache, otm, logfont, analysis, advance,
2239 lookup, lookup_index, glyphs, g, glyph_count, goffset);
2240 }
2241 return 1;
2242 }
2243 }
2244
2245 TRACE("Not covered\n");
2246 continue;
2247 }
2248 else if (GET_BE_WORD(cpf2->PosFormat) == 3)
2249 {
2250 static int once;
2251 if (!once++)
2252 FIXME(" TODO: subtype 3\n");
2253 continue;
2254 }
2255 else
2256 FIXME("Unhandled Contextual Positioning Format %i\n",GET_BE_WORD(cpf2->PosFormat));
2257 }
2258 return 1;
2259}
#define index(s, c)
Definition: various.h:29
r l[0]
Definition: byte_order.h:168
#define NULL
Definition: types.h:112
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLuint index
Definition: glext.h:6031
static WORD OT_get_glyph_class(const void *table, WORD glyph)
Definition: opentype.c:714
GPOS_PosLookupRecord PosLookupRecord[1]
Definition: opentype.c:593
WORD PosClassRuleCnt
Definition: opentype.c:582
WORD PosClassRule[1]
Definition: opentype.c:583

Referenced by GPOS_apply_lookup().

◆ GPOS_apply_CursiveAttachment()

static void GPOS_apply_CursiveAttachment ( const OT_LookupTable look,
const SCRIPT_ANALYSIS analysis,
const WORD glyphs,
unsigned int  glyph_index,
unsigned int  glyph_count,
unsigned int  ppem,
POINT pt 
)
static

Definition at line 1858 of file opentype.c.

1860{
1861 int j;
1862 int write_dir = (analysis->fRTL && !analysis->fLogicalOrder) ? -1 : 1;
1863
1864 if (glyph_index + write_dir >= glyph_count)
1865 return;
1866
1867 TRACE("Cursive Attachment Positioning Subtable\n");
1868
1869 for (j = 0; j < GET_BE_WORD(look->SubTableCount); j++)
1870 {
1872 if (GET_BE_WORD(cpf1->PosFormat) == 1)
1873 {
1874 int index_exit, index_entry;
1875 WORD offset = GET_BE_WORD( cpf1->Coverage );
1876 index_exit = GSUB_is_glyph_covered((const BYTE*)cpf1+offset, glyphs[glyph_index]);
1877 if (index_exit != -1 && cpf1->EntryExitRecord[index_exit].ExitAnchor!= 0)
1878 {
1879 index_entry = GSUB_is_glyph_covered((const BYTE*)cpf1+offset, glyphs[glyph_index+write_dir]);
1880 if (index_entry != -1 && cpf1->EntryExitRecord[index_entry].EntryAnchor != 0)
1881 {
1882 POINT exit_pt, entry_pt;
1883 offset = GET_BE_WORD(cpf1->EntryExitRecord[index_exit].ExitAnchor);
1884 GPOS_get_anchor_values((const BYTE*)cpf1 + offset, &exit_pt, ppem);
1885 offset = GET_BE_WORD(cpf1->EntryExitRecord[index_entry].EntryAnchor);
1886 GPOS_get_anchor_values((const BYTE*)cpf1 + offset, &entry_pt, ppem);
1887 TRACE("Found linkage %x[%s] %x[%s]\n",glyphs[glyph_index], wine_dbgstr_point(&exit_pt), glyphs[glyph_index+write_dir], wine_dbgstr_point(&entry_pt));
1888 pt->x = entry_pt.x - exit_pt.x;
1889 pt->y = entry_pt.y - exit_pt.y;
1890 return;
1891 }
1892 }
1893 }
1894 else
1895 FIXME("Cursive Attachment Positioning: Format %i Unhandled\n",GET_BE_WORD(cpf1->PosFormat));
1896 }
1897 return;
1898}
#define pt(x, y)
Definition: drawing.c:79
static void GPOS_get_anchor_values(const void *table, POINT *pt, WORD ppem)
Definition: opentype.c:1584
GPOS_EntryExitRecord EntryExitRecord[1]
Definition: opentype.c:496
long y
Definition: polytest.cpp:48
long x
Definition: polytest.cpp:48

Referenced by GPOS_apply_lookup().

◆ GPOS_apply_lookup()

static unsigned int GPOS_apply_lookup ( const ScriptCache script_cache,
const OUTLINETEXTMETRICW otm,
const LOGFONTW logfont,
const SCRIPT_ANALYSIS analysis,
int advance,
const OT_LookupList lookup,
unsigned int  lookup_index,
const WORD glyphs,
unsigned int  glyph_index,
unsigned int  glyph_count,
GOFFSET goffset 
)
static

Definition at line 2382 of file opentype.c.

2386{
2387 int offset;
2388 const OT_LookupTable *look;
2389 int ppem = lpotm->otmTextMetrics.tmAscent + lpotm->otmTextMetrics.tmDescent - lpotm->otmTextMetrics.tmInternalLeading;
2391
2392 offset = GET_BE_WORD(lookup->Lookup[lookup_index]);
2393 look = (const OT_LookupTable*)((const BYTE*)lookup + offset);
2394 type = GET_BE_WORD(look->LookupType);
2395 TRACE("type %#x, flag %#x, subtables %u.\n", type,
2397
2399 {
2400 if (GET_BE_WORD(look->SubTableCount))
2401 {
2402 const GPOS_ExtensionPosFormat1 *ext = (const GPOS_ExtensionPosFormat1 *)((const BYTE *)look + GET_BE_WORD(look->SubTable[0]));
2403 if (GET_BE_WORD(ext->PosFormat) == 1)
2404 {
2405 type = GET_BE_WORD(ext->ExtensionLookupType);
2406 TRACE("extension type %i\n",type);
2407 }
2408 else
2409 {
2410 FIXME("Unhandled Extension Positioning Format %i\n",GET_BE_WORD(ext->PosFormat));
2411 }
2412 }
2413 else
2414 {
2415 WARN("lookup type is Extension Positioning but no extension subtable exists\n");
2416 }
2417 }
2418 switch (type)
2419 {
2421 {
2422 double devX, devY;
2423 POINT adjust = {0,0};
2424 POINT advance = {0,0};
2425 GPOS_apply_SingleAdjustment(look, analysis, glyphs, glyph_index, glyph_count, ppem, &adjust, &advance);
2426 if (adjust.x || adjust.y)
2427 {
2428 GPOS_convert_design_units_to_device(lpotm, lplogfont, adjust.x, adjust.y, &devX, &devY);
2429 pGoffset[glyph_index].du += round(devX);
2430 pGoffset[glyph_index].dv += round(devY);
2431 }
2432 if (advance.x || advance.y)
2433 {
2434 GPOS_convert_design_units_to_device(lpotm, lplogfont, advance.x, advance.y, &devX, &devY);
2435 piAdvance[glyph_index] += round(devX);
2436 if (advance.y)
2437 FIXME("Unhandled adjustment to Y advancement\n");
2438 }
2439 break;
2440 }
2441
2443 {
2444 POINT advance[2]= {{0,0},{0,0}};
2445 POINT adjust[2]= {{0,0},{0,0}};
2446 double devX, devY;
2447 int index_offset;
2448 int write_dir = (analysis->fRTL && !analysis->fLogicalOrder) ? -1 : 1;
2449 int offset_sign = (analysis->fRTL && analysis->fLogicalOrder) ? -1 : 1;
2450
2451 index_offset = GPOS_apply_PairAdjustment(look, analysis, glyphs,
2452 glyph_index, glyph_count, ppem, adjust, advance);
2453 if (adjust[0].x || adjust[0].y)
2454 {
2455 GPOS_convert_design_units_to_device(lpotm, lplogfont, adjust[0].x, adjust[0].y, &devX, &devY);
2456 pGoffset[glyph_index].du += round(devX) * offset_sign;
2457 pGoffset[glyph_index].dv += round(devY);
2458 }
2459 if (advance[0].x || advance[0].y)
2460 {
2461 GPOS_convert_design_units_to_device(lpotm, lplogfont, advance[0].x, advance[0].y, &devX, &devY);
2462 piAdvance[glyph_index] += round(devX);
2463 }
2464 if (adjust[1].x || adjust[1].y)
2465 {
2466 GPOS_convert_design_units_to_device(lpotm, lplogfont, adjust[1].x, adjust[1].y, &devX, &devY);
2467 pGoffset[glyph_index + write_dir].du += round(devX) * offset_sign;
2468 pGoffset[glyph_index + write_dir].dv += round(devY);
2469 }
2470 if (advance[1].x || advance[1].y)
2471 {
2472 GPOS_convert_design_units_to_device(lpotm, lplogfont, advance[1].x, advance[1].y, &devX, &devY);
2473 piAdvance[glyph_index + write_dir] += round(devX);
2474 }
2475 return index_offset;
2476 }
2477
2479 {
2480 POINT desU = {0,0};
2481 double devX, devY;
2482 int write_dir = (analysis->fRTL && !analysis->fLogicalOrder) ? -1 : 1;
2483
2484 GPOS_apply_CursiveAttachment(look, analysis, glyphs, glyph_index, glyph_count, ppem, &desU);
2485 if (desU.x || desU.y)
2486 {
2487 GPOS_convert_design_units_to_device(lpotm, lplogfont, desU.x, desU.y, &devX, &devY);
2488 /* Windows does not appear to apply X offsets here */
2489 pGoffset[glyph_index].dv = round(devY) + pGoffset[glyph_index+write_dir].dv;
2490 }
2491 break;
2492 }
2493
2495 {
2496 double devX, devY;
2497 POINT desU = {0,0};
2498 int base_index = GPOS_apply_MarkToBase(script_cache, look, analysis,
2499 glyphs, glyph_index, glyph_count, ppem, &desU);
2500 if (base_index != -1)
2501 {
2502 GPOS_convert_design_units_to_device(lpotm, lplogfont, desU.x, desU.y, &devX, &devY);
2503 if (!analysis->fRTL) pGoffset[glyph_index].du = round(devX) - piAdvance[base_index];
2504 else
2505 {
2506 if (analysis->fLogicalOrder) devX *= -1;
2507 pGoffset[glyph_index].du = round(devX);
2508 }
2509 pGoffset[glyph_index].dv = round(devY);
2510 }
2511 break;
2512 }
2513
2515 {
2516 double devX, devY;
2517 POINT desU = {0,0};
2518 GPOS_apply_MarkToLigature(look, analysis, glyphs, glyph_index, glyph_count, ppem, &desU);
2519 if (desU.x || desU.y)
2520 {
2521 GPOS_convert_design_units_to_device(lpotm, lplogfont, desU.x, desU.y, &devX, &devY);
2522 pGoffset[glyph_index].du = (round(devX) - piAdvance[glyph_index-1]);
2523 pGoffset[glyph_index].dv = round(devY);
2524 }
2525 break;
2526 }
2527
2529 {
2530 double devX, devY;
2531 POINT desU = {0,0};
2532 int write_dir = (analysis->fRTL && !analysis->fLogicalOrder) ? -1 : 1;
2533 if (GPOS_apply_MarkToMark(look, analysis, glyphs, glyph_index, glyph_count, ppem, &desU))
2534 {
2535 GPOS_convert_design_units_to_device(lpotm, lplogfont, desU.x, desU.y, &devX, &devY);
2536 if (analysis->fRTL && analysis->fLogicalOrder) devX *= -1;
2537 pGoffset[glyph_index].du = round(devX) + pGoffset[glyph_index - write_dir].du;
2538 pGoffset[glyph_index].dv = round(devY) + pGoffset[glyph_index - write_dir].dv;
2539 }
2540 break;
2541 }
2542
2544 return GPOS_apply_ContextPos(script_cache, lpotm, lplogfont, analysis, piAdvance,
2545 lookup, look, glyphs, glyph_index, glyph_count, pGoffset);
2546
2548 return GPOS_apply_ChainContextPos(script_cache, lpotm, lplogfont, analysis, piAdvance,
2549 lookup, look, glyphs, glyph_index, glyph_count, pGoffset);
2550
2551 default:
2552 FIXME("Unhandled GPOS lookup type %#x.\n", type);
2553 }
2554 return 1;
2555}
static const WCHAR *const ext[]
Definition: module.c:53
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
GLint GLint GLint GLint GLint GLint y
Definition: gl.h:1548
static void GPOS_apply_SingleAdjustment(const OT_LookupTable *look, const SCRIPT_ANALYSIS *analysis, const WORD *glyphs, unsigned int glyph_index, unsigned int glyph_count, unsigned int ppem, POINT *adjust, POINT *advance)
Definition: opentype.c:1695
gpos_lookup_type
Definition: opentype.c:53
static int GPOS_apply_PairAdjustment(const OT_LookupTable *look, const SCRIPT_ANALYSIS *analysis, const WORD *glyphs, unsigned int glyph_index, unsigned int glyph_count, unsigned int ppem, POINT *adjust, POINT *advance)
Definition: opentype.c:1770
static unsigned int GPOS_apply_ChainContextPos(const ScriptCache *script_cache, const OUTLINETEXTMETRICW *otm, const LOGFONTW *logfont, const SCRIPT_ANALYSIS *analysis, int *advance, const OT_LookupList *lookup, const OT_LookupTable *look, const WORD *glyphs, unsigned int glyph_index, unsigned int glyph_count, GOFFSET *goffset)
Definition: opentype.c:2261
static void GPOS_apply_CursiveAttachment(const OT_LookupTable *look, const SCRIPT_ANALYSIS *analysis, const WORD *glyphs, unsigned int glyph_index, unsigned int glyph_count, unsigned int ppem, POINT *pt)
Definition: opentype.c:1858
#define round(x)
Definition: opentype.c:47
static int GPOS_apply_MarkToBase(const ScriptCache *script_cache, const OT_LookupTable *look, const SCRIPT_ANALYSIS *analysis, const WORD *glyphs, unsigned int glyph_index, unsigned int glyph_count, unsigned int ppem, POINT *pt)
Definition: opentype.c:1900
static void GPOS_convert_design_units_to_device(const OUTLINETEXTMETRICW *otm, const LOGFONTW *logfont, int desX, int desY, double *devX, double *devY)
Definition: opentype.c:1636
static void GPOS_apply_MarkToLigature(const OT_LookupTable *look, const SCRIPT_ANALYSIS *analysis, const WORD *glyphs, unsigned int glyph_index, unsigned int glyph_count, unsigned int ppem, POINT *pt)
Definition: opentype.c:1985
static BOOL GPOS_apply_MarkToMark(const OT_LookupTable *look, const SCRIPT_ANALYSIS *analysis, const WORD *glyphs, unsigned int glyph_index, unsigned int glyph_count, unsigned int ppem, POINT *pt)
Definition: opentype.c:2075
static unsigned int GPOS_apply_ContextPos(const ScriptCache *script_cache, const OUTLINETEXTMETRICW *otm, const LOGFONTW *logfont, const SCRIPT_ANALYSIS *analysis, int *advance, const OT_LookupList *lookup, const OT_LookupTable *look, const WORD *glyphs, unsigned int glyph_index, unsigned int glyph_count, GOFFSET *goffset)
Definition: opentype.c:2142
WORD SubTable[1]
Definition: opentype.c:196
WORD LookupFlag
Definition: opentype.c:194
WORD LookupType
Definition: opentype.c:193

Referenced by GPOS_apply_ChainContextPos(), GPOS_apply_ContextPos(), and OpenType_apply_GPOS_lookup().

◆ GPOS_apply_MarkToBase()

static int GPOS_apply_MarkToBase ( const ScriptCache script_cache,
const OT_LookupTable look,
const SCRIPT_ANALYSIS analysis,
const WORD glyphs,
unsigned int  glyph_index,
unsigned int  glyph_count,
unsigned int  ppem,
POINT pt 
)
static

Definition at line 1900 of file opentype.c.

1903{
1904 int j;
1905 int write_dir = (analysis->fRTL && !analysis->fLogicalOrder) ? -1 : 1;
1906 const void *glyph_class_table = NULL;
1907 int rc = -1;
1908
1909 if (script_cache->GDEF_Table)
1910 {
1911 const GDEF_Header *header = script_cache->GDEF_Table;
1912 WORD offset = GET_BE_WORD( header->GlyphClassDef );
1913 if (offset)
1914 glyph_class_table = (const BYTE *)script_cache->GDEF_Table + offset;
1915 }
1916
1917 TRACE("MarkToBase Attachment Positioning Subtable\n");
1918
1919 for (j = 0; j < GET_BE_WORD(look->SubTableCount); j++)
1920 {
1922 if (GET_BE_WORD(mbpf1->PosFormat) == 1)
1923 {
1924 int offset = GET_BE_WORD(mbpf1->MarkCoverage);
1925 int mark_index;
1926 mark_index = GSUB_is_glyph_covered((const BYTE*)mbpf1+offset, glyphs[glyph_index]);
1927 if (mark_index != -1)
1928 {
1929 int base_index;
1930 int base_glyph = glyph_index - write_dir;
1931
1932 if (glyph_class_table)
1933 {
1934 while (OT_get_glyph_class(glyph_class_table, glyphs[base_glyph]) == MarkGlyph && base_glyph > 0 && base_glyph < glyph_count)
1935 base_glyph -= write_dir;
1936 }
1937
1939 base_index = GSUB_is_glyph_covered((const BYTE*)mbpf1+offset, glyphs[base_glyph]);
1940 if (base_index != -1)
1941 {
1942 const GPOS_MarkArray *ma;
1943 const GPOS_MarkRecord *mr;
1944 const GPOS_BaseArray *ba;
1945 const GPOS_BaseRecord *br;
1946 int mark_class;
1947 int class_count = GET_BE_WORD(mbpf1->ClassCount);
1948 int baserecord_size;
1949 POINT base_pt;
1950 POINT mark_pt;
1951 TRACE("Mark %x(%i) and base %x(%i)\n",glyphs[glyph_index], mark_index, glyphs[base_glyph], base_index);
1952 offset = GET_BE_WORD(mbpf1->MarkArray);
1953 ma = (const GPOS_MarkArray*)((const BYTE*)mbpf1 + offset);
1954 if (mark_index > GET_BE_WORD(ma->MarkCount))
1955 {
1956 ERR("Mark index exceeded mark count\n");
1957 return -1;
1958 }
1959 mr = &ma->MarkRecord[mark_index];
1960 mark_class = GET_BE_WORD(mr->Class);
1961 TRACE("Mark Class %i total classes %i\n",mark_class,class_count);
1962 offset = GET_BE_WORD(mbpf1->BaseArray);
1963 ba = (const GPOS_BaseArray*)((const BYTE*)mbpf1 + offset);
1964 baserecord_size = class_count * sizeof(WORD);
1965 br = (const GPOS_BaseRecord*)((const BYTE*)ba + sizeof(WORD) + (baserecord_size * base_index));
1966 offset = GET_BE_WORD(br->BaseAnchor[mark_class]);
1967 GPOS_get_anchor_values((const BYTE*)ba + offset, &base_pt, ppem);
1969 GPOS_get_anchor_values((const BYTE*)ma + offset, &mark_pt, ppem);
1970 TRACE("Offset on base is %s design units\n",wine_dbgstr_point(&base_pt));
1971 TRACE("Offset on mark is %s design units\n",wine_dbgstr_point(&mark_pt));
1972 pt->x += base_pt.x - mark_pt.x;
1973 pt->y += base_pt.y - mark_pt.y;
1974 TRACE("Resulting cumulative offset is %s design units\n",wine_dbgstr_point(pt));
1975 rc = base_glyph;
1976 }
1977 }
1978 }
1979 else
1980 FIXME("Unhandled Mark To Base Format %i\n",GET_BE_WORD(mbpf1->PosFormat));
1981 }
1982 return rc;
1983}
#define ERR(fmt,...)
Definition: debug.h:110
GPOS_MarkRecord MarkRecord[1]
Definition: opentype.c:524
WORD MarkCount
Definition: opentype.c:523
void * GDEF_Table

Referenced by GPOS_apply_lookup().

◆ GPOS_apply_MarkToLigature()

static void GPOS_apply_MarkToLigature ( const OT_LookupTable look,
const SCRIPT_ANALYSIS analysis,
const WORD glyphs,
unsigned int  glyph_index,
unsigned int  glyph_count,
unsigned int  ppem,
POINT pt 
)
static

Definition at line 1985 of file opentype.c.

1987{
1988 int j;
1989 int write_dir = (analysis->fRTL && !analysis->fLogicalOrder) ? -1 : 1;
1990
1991 TRACE("MarkToLigature Attachment Positioning Subtable\n");
1992
1993 for (j = 0; j < GET_BE_WORD(look->SubTableCount); j++)
1994 {
1996 if (GET_BE_WORD(mlpf1->PosFormat) == 1)
1997 {
1998 int offset = GET_BE_WORD(mlpf1->MarkCoverage);
1999 int mark_index;
2000 mark_index = GSUB_is_glyph_covered((const BYTE*)mlpf1+offset, glyphs[glyph_index]);
2001 if (mark_index != -1)
2002 {
2003 int ligature_index;
2005 ligature_index = GSUB_is_glyph_covered((const BYTE*)mlpf1+offset, glyphs[glyph_index - write_dir]);
2006 if (ligature_index != -1)
2007 {
2008 const GPOS_MarkArray *ma;
2009 const GPOS_MarkRecord *mr;
2010
2011 const GPOS_LigatureArray *la;
2012 const GPOS_LigatureAttach *lt;
2013 int mark_class;
2014 int class_count = GET_BE_WORD(mlpf1->ClassCount);
2015 int component_count;
2016 int component_size;
2017 int i;
2018 POINT ligature_pt;
2019 POINT mark_pt;
2020
2021 TRACE("Mark %x(%i) and ligature %x(%i)\n",glyphs[glyph_index], mark_index, glyphs[glyph_index - write_dir], ligature_index);
2022 offset = GET_BE_WORD(mlpf1->MarkArray);
2023 ma = (const GPOS_MarkArray*)((const BYTE*)mlpf1 + offset);
2024 if (mark_index > GET_BE_WORD(ma->MarkCount))
2025 {
2026 ERR("Mark index exceeded mark count\n");
2027 return;
2028 }
2029 mr = &ma->MarkRecord[mark_index];
2030 mark_class = GET_BE_WORD(mr->Class);
2031 TRACE("Mark Class %i total classes %i\n",mark_class,class_count);
2033 la = (const GPOS_LigatureArray*)((const BYTE*)mlpf1 + offset);
2034 if (ligature_index > GET_BE_WORD(la->LigatureCount))
2035 {
2036 ERR("Ligature index exceeded ligature count\n");
2037 return;
2038 }
2039 offset = GET_BE_WORD(la->LigatureAttach[ligature_index]);
2040 lt = (const GPOS_LigatureAttach*)((const BYTE*)la + offset);
2041
2043 component_size = class_count * sizeof(WORD);
2044 offset = 0;
2045 for (i = 0; i < component_count && !offset; i++)
2046 {
2047 int k;
2048 const GPOS_ComponentRecord *cr = (const GPOS_ComponentRecord*)((const BYTE*)lt->ComponentRecord + (component_size * i));
2049 for (k = 0; k < class_count && !offset; k++)
2051 cr = (const GPOS_ComponentRecord*)((const BYTE*)cr + component_size);
2052 }
2053 if (!offset)
2054 {
2055 ERR("Failed to find available ligature connection point\n");
2056 return;
2057 }
2058
2059 GPOS_get_anchor_values((const BYTE*)lt + offset, &ligature_pt, ppem);
2061 GPOS_get_anchor_values((const BYTE*)ma + offset, &mark_pt, ppem);
2062 TRACE("Offset on ligature is %s design units\n",wine_dbgstr_point(&ligature_pt));
2063 TRACE("Offset on mark is %s design units\n",wine_dbgstr_point(&mark_pt));
2064 pt->x += ligature_pt.x - mark_pt.x;
2065 pt->y += ligature_pt.y - mark_pt.y;
2066 TRACE("Resulting cumulative offset is %s design units\n",wine_dbgstr_point(pt));
2067 }
2068 }
2069 }
2070 else
2071 FIXME("Unhandled Mark To Ligature Format %i\n",GET_BE_WORD(mlpf1->PosFormat));
2072 }
2073}
unsigned int component_count
unsigned int component_size
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
WORD LigatureAnchor[1]
Definition: opentype.c:542
WORD LigatureAttach[1]
Definition: opentype.c:538
GPOS_ComponentRecord ComponentRecord[1]
Definition: opentype.c:547

Referenced by GPOS_apply_lookup().

◆ GPOS_apply_MarkToMark()

static BOOL GPOS_apply_MarkToMark ( const OT_LookupTable look,
const SCRIPT_ANALYSIS analysis,
const WORD glyphs,
unsigned int  glyph_index,
unsigned int  glyph_count,
unsigned int  ppem,
POINT pt 
)
static

Definition at line 2075 of file opentype.c.

2077{
2078 int j;
2079 BOOL rc = FALSE;
2080 int write_dir = (analysis->fRTL && !analysis->fLogicalOrder) ? -1 : 1;
2081
2082 TRACE("MarkToMark Attachment Positioning Subtable\n");
2083
2084 for (j = 0; j < GET_BE_WORD(look->SubTableCount); j++)
2085 {
2087 if (GET_BE_WORD(mmpf1->PosFormat) == 1)
2088 {
2089 int offset = GET_BE_WORD(mmpf1->Mark1Coverage);
2090 int mark_index;
2091 mark_index = GSUB_is_glyph_covered((const BYTE*)mmpf1+offset, glyphs[glyph_index]);
2092 if (mark_index != -1)
2093 {
2094 int mark2_index;
2096 mark2_index = GSUB_is_glyph_covered((const BYTE*)mmpf1+offset, glyphs[glyph_index - write_dir]);
2097 if (mark2_index != -1)
2098 {
2099 const GPOS_MarkArray *ma;
2100 const GPOS_MarkRecord *mr;
2101 const GPOS_Mark2Array *m2a;
2102 const GPOS_Mark2Record *m2r;
2103 int mark_class;
2104 int class_count = GET_BE_WORD(mmpf1->ClassCount);
2105 int mark2record_size;
2106 POINT mark2_pt;
2107 POINT mark_pt;
2108 TRACE("Mark %x(%i) and Mark2 %x(%i)\n",glyphs[glyph_index], mark_index, glyphs[glyph_index - write_dir], mark2_index);
2109 offset = GET_BE_WORD(mmpf1->Mark1Array);
2110 ma = (const GPOS_MarkArray*)((const BYTE*)mmpf1 + offset);
2111 if (mark_index > GET_BE_WORD(ma->MarkCount))
2112 {
2113 ERR("Mark index exceeded mark count\n");
2114 return FALSE;
2115 }
2116 mr = &ma->MarkRecord[mark_index];
2117 mark_class = GET_BE_WORD(mr->Class);
2118 TRACE("Mark Class %i total classes %i\n",mark_class,class_count);
2119 offset = GET_BE_WORD(mmpf1->Mark2Array);
2120 m2a = (const GPOS_Mark2Array*)((const BYTE*)mmpf1 + offset);
2121 mark2record_size = class_count * sizeof(WORD);
2122 m2r = (const GPOS_Mark2Record*)((const BYTE*)m2a + sizeof(WORD) + (mark2record_size * mark2_index));
2123 offset = GET_BE_WORD(m2r->Mark2Anchor[mark_class]);
2124 GPOS_get_anchor_values((const BYTE*)m2a + offset, &mark2_pt, ppem);
2126 GPOS_get_anchor_values((const BYTE*)ma + offset, &mark_pt, ppem);
2127 TRACE("Offset on mark2 is %s design units\n",wine_dbgstr_point(&mark2_pt));
2128 TRACE("Offset on mark is %s design units\n",wine_dbgstr_point(&mark_pt));
2129 pt->x += mark2_pt.x - mark_pt.x;
2130 pt->y += mark2_pt.y - mark_pt.y;
2131 TRACE("Resulting cumulative offset is %s design units\n",wine_dbgstr_point(pt));
2132 rc = TRUE;
2133 }
2134 }
2135 }
2136 else
2137 FIXME("Unhandled Mark To Mark Format %i\n",GET_BE_WORD(mmpf1->PosFormat));
2138 }
2139 return rc;
2140}
#define FALSE
Definition: types.h:117
unsigned int BOOL
Definition: ntddk_ex.h:94

Referenced by GPOS_apply_lookup().

◆ GPOS_apply_PairAdjustment()

static int GPOS_apply_PairAdjustment ( const OT_LookupTable look,
const SCRIPT_ANALYSIS analysis,
const WORD glyphs,
unsigned int  glyph_index,
unsigned int  glyph_count,
unsigned int  ppem,
POINT adjust,
POINT advance 
)
static

Definition at line 1770 of file opentype.c.

1773{
1774 int j;
1775 int write_dir = (analysis->fRTL && !analysis->fLogicalOrder) ? -1 : 1;
1776
1777 if (glyph_index + write_dir >= glyph_count)
1778 return 1;
1779
1780 TRACE("Pair Adjustment Positioning Subtable\n");
1781
1782 for (j = 0; j < GET_BE_WORD(look->SubTableCount); j++)
1783 {
1784 const GPOS_PairPosFormat1 *ppf1 = (const GPOS_PairPosFormat1*)GPOS_get_subtable(look, j);
1785 WORD offset;
1786 if (GET_BE_WORD(ppf1->PosFormat) == 1)
1787 {
1788 int index;
1789 WORD ValueFormat1 = GET_BE_WORD(ppf1->ValueFormat1);
1790 WORD ValueFormat2 = GET_BE_WORD(ppf1->ValueFormat2);
1791 INT val_fmt1_size = GPOS_get_value_record( ValueFormat1, NULL, NULL );
1792 INT val_fmt2_size = GPOS_get_value_record( ValueFormat2, NULL, NULL );
1793 offset = GET_BE_WORD(ppf1->Coverage);
1794 index = GSUB_is_glyph_covered((const BYTE*)ppf1+offset, glyphs[glyph_index]);
1795 if (index != -1 && index < GET_BE_WORD(ppf1->PairSetCount))
1796 {
1797 int k;
1798 int pair_count;
1799 const GPOS_PairSet *ps;
1800 const GPOS_PairValueRecord *pair_val_rec;
1802 ps = (const GPOS_PairSet*)((const BYTE*)ppf1+offset);
1803 pair_count = GET_BE_WORD(ps->PairValueCount);
1804 pair_val_rec = ps->PairValueRecord;
1805 for (k = 0; k < pair_count; k++)
1806 {
1807 WORD second_glyph = GET_BE_WORD(pair_val_rec->SecondGlyph);
1808 if (glyphs[glyph_index+write_dir] == second_glyph)
1809 {
1810 int next = 1;
1811 TRACE("Format 1: Found Pair %x,%x\n",glyphs[glyph_index],glyphs[glyph_index+write_dir]);
1812 apply_pair_value(ppf1, ValueFormat1, ValueFormat2,
1813 pair_val_rec->Value1, ppem, adjust, advance);
1814 if (ValueFormat2) next++;
1815 return next;
1816 }
1817 pair_val_rec = (const GPOS_PairValueRecord *)(pair_val_rec->Value1 + val_fmt1_size + val_fmt2_size);
1818 }
1819 }
1820 }
1821 else if (GET_BE_WORD(ppf1->PosFormat) == 2)
1822 {
1823 const GPOS_PairPosFormat2 *ppf2 = (const GPOS_PairPosFormat2*)ppf1;
1824 int index;
1825 WORD ValueFormat1 = GET_BE_WORD( ppf2->ValueFormat1 );
1826 WORD ValueFormat2 = GET_BE_WORD( ppf2->ValueFormat2 );
1827 INT val_fmt1_size = GPOS_get_value_record( ValueFormat1, NULL, NULL );
1828 INT val_fmt2_size = GPOS_get_value_record( ValueFormat2, NULL, NULL );
1829 WORD class1_count = GET_BE_WORD( ppf2->Class1Count );
1830 WORD class2_count = GET_BE_WORD( ppf2->Class2Count );
1831
1832 offset = GET_BE_WORD( ppf2->Coverage );
1833 index = GSUB_is_glyph_covered( (const BYTE*)ppf2 + offset, glyphs[glyph_index] );
1834 if (index != -1)
1835 {
1836 WORD class1, class2;
1837 class1 = OT_get_glyph_class( (const BYTE *)ppf2 + GET_BE_WORD(ppf2->ClassDef1), glyphs[glyph_index] );
1838 class2 = OT_get_glyph_class( (const BYTE *)ppf2 + GET_BE_WORD(ppf2->ClassDef2), glyphs[glyph_index + write_dir] );
1839 if (class1 < class1_count && class2 < class2_count)
1840 {
1841 const WORD *pair_val = ppf2->Class1Record + (class1 * class2_count + class2) * (val_fmt1_size + val_fmt2_size);
1842 int next = 1;
1843
1844 TRACE( "Format 2: Found Pair %x,%x\n", glyphs[glyph_index], glyphs[glyph_index + write_dir] );
1845
1846 apply_pair_value(ppf2, ValueFormat1, ValueFormat2, pair_val, ppem, adjust, advance);
1847 if (ValueFormat2) next++;
1848 return next;
1849 }
1850 }
1851 }
1852 else
1853 FIXME("Pair Adjustment Positioning: Format %i Unhandled\n",GET_BE_WORD(ppf1->PosFormat));
1854 }
1855 return 1;
1856}
static void apply_pair_value(const void *pos_table, WORD val_fmt1, WORD val_fmt2, const WORD *pair, INT ppem, POINT *adjust, POINT *advance)
Definition: opentype.c:1746
static unsigned __int64 next
Definition: rand_nt.c:6
WORD PairSetOffset[1]
Definition: opentype.c:461
WORD Class1Record[1]
Definition: opentype.c:473
WORD PairValueCount
Definition: opentype.c:483
GPOS_PairValueRecord PairValueRecord[1]
Definition: opentype.c:484

Referenced by GPOS_apply_lookup().

◆ GPOS_apply_SingleAdjustment()

static void GPOS_apply_SingleAdjustment ( const OT_LookupTable look,
const SCRIPT_ANALYSIS analysis,
const WORD glyphs,
unsigned int  glyph_index,
unsigned int  glyph_count,
unsigned int  ppem,
POINT adjust,
POINT advance 
)
static

Definition at line 1695 of file opentype.c.

1698{
1699 int j;
1700
1701 TRACE("Single Adjustment Positioning Subtable\n");
1702
1703 for (j = 0; j < GET_BE_WORD(look->SubTableCount); j++)
1704 {
1706 WORD offset;
1707 if (GET_BE_WORD(spf1->PosFormat) == 1)
1708 {
1709 offset = GET_BE_WORD(spf1->Coverage);
1710 if (GSUB_is_glyph_covered((const BYTE*)spf1+offset, glyphs[glyph_index]) != -1)
1711 {
1712 GPOS_ValueRecord ValueRecord = {0,0,0,0,0,0,0,0};
1713 WORD ValueFormat = GET_BE_WORD(spf1->ValueFormat);
1714 GPOS_get_value_record(ValueFormat, spf1->Value, &ValueRecord);
1715 GPOS_get_value_record_offsets((const BYTE *)spf1, &ValueRecord, ValueFormat, ppem, adjust, advance);
1716 TRACE("Glyph Adjusted by %i,%i\n",ValueRecord.XPlacement,ValueRecord.YPlacement);
1717 }
1718 }
1719 else if (GET_BE_WORD(spf1->PosFormat) == 2)
1720 {
1721 int index;
1722 const GPOS_SinglePosFormat2 *spf2;
1723 spf2 = (const GPOS_SinglePosFormat2*)spf1;
1724 offset = GET_BE_WORD(spf2->Coverage);
1725 index = GSUB_is_glyph_covered((const BYTE*)spf2+offset, glyphs[glyph_index]);
1726 if (index != -1)
1727 {
1728 int size;
1729 GPOS_ValueRecord ValueRecord = {0,0,0,0,0,0,0,0};
1730 WORD ValueFormat = GET_BE_WORD(spf2->ValueFormat);
1731 size = GPOS_get_value_record(ValueFormat, spf2->Value, &ValueRecord);
1732 if (index > 0)
1733 {
1734 offset = size * index;
1735 GPOS_get_value_record(ValueFormat, &spf2->Value[offset], &ValueRecord);
1736 }
1737 GPOS_get_value_record_offsets((const BYTE *)spf2, &ValueRecord, ValueFormat, ppem, adjust, advance);
1738 TRACE("Glyph Adjusted by %i,%i\n",ValueRecord.XPlacement,ValueRecord.YPlacement);
1739 }
1740 }
1741 else
1742 FIXME("Single Adjustment Positioning: Format %i Unhandled\n",GET_BE_WORD(spf1->PosFormat));
1743 }
1744}

Referenced by GPOS_apply_lookup().

◆ GPOS_convert_design_units_to_device()

static void GPOS_convert_design_units_to_device ( const OUTLINETEXTMETRICW otm,
const LOGFONTW logfont,
int  desX,
int  desY,
double devX,
double devY 
)
static

Definition at line 1636 of file opentype.c.

1638{
1640
1641 TRACE("emHeight %i lfWidth %i\n",emHeight, logfont->lfWidth);
1642 *devX = (desX * emHeight) / (double)otm->otmEMSquare;
1643 *devY = (desY * emHeight) / (double)otm->otmEMSquare;
1644 if (logfont->lfWidth)
1645 FIXME("Font with lfWidth set not handled properly.\n");
1646}
LONG lfWidth
Definition: dimm.idl:60
TEXTMETRICW otmTextMetrics
Definition: wingdi.h:2514
LONG tmAscent
Definition: wingdi.h:2384
LONG tmInternalLeading
Definition: wingdi.h:2386
LONG tmDescent
Definition: wingdi.h:2385

Referenced by GPOS_apply_lookup().

◆ GPOS_get_anchor_values()

static void GPOS_get_anchor_values ( const void table,
POINT pt,
WORD  ppem 
)
static

Definition at line 1584 of file opentype.c.

1585{
1586 const GPOS_AnchorFormat1* anchor1 = (const GPOS_AnchorFormat1*)table;
1587
1588 switch (GET_BE_WORD(anchor1->AnchorFormat))
1589 {
1590 case 1:
1591 {
1592 TRACE("Anchor Format 1\n");
1593 pt->x = (short)GET_BE_WORD(anchor1->XCoordinate);
1594 pt->y = (short)GET_BE_WORD(anchor1->YCoordinate);
1595 break;
1596 }
1597 case 2:
1598 {
1599 const GPOS_AnchorFormat2* anchor2 = (const GPOS_AnchorFormat2*)table;
1600 TRACE("Anchor Format 2\n");
1601 pt->x = (short)GET_BE_WORD(anchor2->XCoordinate);
1602 pt->y = (short)GET_BE_WORD(anchor2->YCoordinate);
1603 break;
1604 }
1605 case 3:
1606 {
1607 int offset;
1608 const GPOS_AnchorFormat3* anchor3 = (const GPOS_AnchorFormat3*)table;
1609 TRACE("Anchor Format 3\n");
1610 pt->x = (short)GET_BE_WORD(anchor3->XCoordinate);
1611 pt->y = (short)GET_BE_WORD(anchor3->YCoordinate);
1612 offset = GET_BE_WORD(anchor3->XDeviceTable);
1613 TRACE("ppem %i\n",ppem);
1614 if (offset)
1615 {
1616 const OT_DeviceTable* DeviceTableX = NULL;
1617 DeviceTableX = (const OT_DeviceTable*)((const BYTE*)anchor3 + offset);
1618 pt->x += GPOS_get_device_table_value(DeviceTableX, ppem);
1619 }
1620 offset = GET_BE_WORD(anchor3->YDeviceTable);
1621 if (offset)
1622 {
1623 const OT_DeviceTable* DeviceTableY = NULL;
1624 DeviceTableY = (const OT_DeviceTable*)((const BYTE*)anchor3 + offset);
1625 pt->y += GPOS_get_device_table_value(DeviceTableY, ppem);
1626 }
1627 break;
1628 }
1629 default:
1630 ERR("Unknown Anchor Format %i\n",GET_BE_WORD(anchor1->AnchorFormat));
1631 pt->x = 0;
1632 pt->y = 0;
1633 }
1634}
unsigned short(__cdecl typeof(TIFFCurrentDirectory))(struct tiff *)
Definition: typeof.h:94
static INT GPOS_get_device_table_value(const OT_DeviceTable *DeviceTable, WORD ppem)
Definition: opentype.c:1557

Referenced by GPOS_apply_CursiveAttachment(), GPOS_apply_MarkToBase(), GPOS_apply_MarkToLigature(), and GPOS_apply_MarkToMark().

◆ GPOS_get_device_table_value()

static INT GPOS_get_device_table_value ( const OT_DeviceTable DeviceTable,
WORD  ppem 
)
static

Definition at line 1557 of file opentype.c.

1558{
1559 static const WORD mask[3] = {3,0xf,0xff};
1560 if (DeviceTable && ppem >= GET_BE_WORD(DeviceTable->StartSize) && ppem <= GET_BE_WORD(DeviceTable->EndSize))
1561 {
1562 WORD format = GET_BE_WORD(DeviceTable->DeltaFormat);
1563 int index = ppem - GET_BE_WORD(DeviceTable->StartSize);
1564 int value;
1565
1566 TRACE("device table, format %#x, index %i\n", format, index);
1567
1568 if (format < 1 || format > 3)
1569 {
1570 WARN("invalid delta format %#x\n", format);
1571 return 0;
1572 }
1573
1574 index = index << format;
1575 value = (DeviceTable->DeltaValue[index/sizeof(WORD)] << (index%sizeof(WORD)))&mask[format-1];
1576 TRACE("offset %i, value %i\n",index, value);
1577 if (value > mask[format-1]/2)
1578 value = -1 * ((mask[format-1]+1) - value);
1579 return value;
1580 }
1581 return 0;
1582}
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
Definition: gl.h:1546
GLenum GLint GLuint mask
Definition: glext.h:6028
WORD DeltaValue[1]
Definition: opentype.c:405
WORD DeltaFormat
Definition: opentype.c:404
WORD StartSize
Definition: opentype.c:402
Definition: pdh_main.c:94

Referenced by GPOS_get_anchor_values(), and GPOS_get_value_record_offsets().

◆ GPOS_get_subtable()

static const BYTE * GPOS_get_subtable ( const OT_LookupTable look,
int  index 
)
static

Definition at line 1676 of file opentype.c.

1677{
1678 int offset = GET_BE_WORD(look->SubTable[index]);
1679
1681 {
1682 const GPOS_ExtensionPosFormat1 *ext = (const GPOS_ExtensionPosFormat1 *)((const BYTE *)look + offset);
1683 if (GET_BE_WORD(ext->PosFormat) == 1)
1684 {
1685 offset += GET_BE_DWORD(ext->ExtensionOffset);
1686 }
1687 else
1688 {
1689 FIXME("Unhandled Extension Positioning Format %i\n",GET_BE_WORD(ext->PosFormat));
1690 }
1691 }
1692 return (const BYTE *)look + offset;
1693}

Referenced by GPOS_apply_ChainContextPos(), GPOS_apply_ContextPos(), GPOS_apply_CursiveAttachment(), GPOS_apply_MarkToBase(), GPOS_apply_MarkToLigature(), GPOS_apply_MarkToMark(), GPOS_apply_PairAdjustment(), and GPOS_apply_SingleAdjustment().

◆ GPOS_get_value_record()

static INT GPOS_get_value_record ( WORD  ValueFormat,
const WORD  data[],
GPOS_ValueRecord record 
)
static

Definition at line 1648 of file opentype.c.

1649{
1650 INT offset = 0;
1651 if (ValueFormat & 0x0001) { if (data) record->XPlacement = GET_BE_WORD(data[offset]); offset++; }
1652 if (ValueFormat & 0x0002) { if (data) record->YPlacement = GET_BE_WORD(data[offset]); offset++; }
1653 if (ValueFormat & 0x0004) { if (data) record->XAdvance = GET_BE_WORD(data[offset]); offset++; }
1654 if (ValueFormat & 0x0008) { if (data) record->YAdvance = GET_BE_WORD(data[offset]); offset++; }
1655 if (ValueFormat & 0x0010) { if (data) record->XPlaDevice = GET_BE_WORD(data[offset]); offset++; }
1656 if (ValueFormat & 0x0020) { if (data) record->YPlaDevice = GET_BE_WORD(data[offset]); offset++; }
1657 if (ValueFormat & 0x0040) { if (data) record->XAdvDevice = GET_BE_WORD(data[offset]); offset++; }
1658 if (ValueFormat & 0x0080) { if (data) record->YAdvDevice = GET_BE_WORD(data[offset]); offset++; }
1659 return offset;
1660}
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950

Referenced by apply_pair_value(), GPOS_apply_PairAdjustment(), and GPOS_apply_SingleAdjustment().

◆ GPOS_get_value_record_offsets()

static void GPOS_get_value_record_offsets ( const BYTE head,
GPOS_ValueRecord ValueRecord,
WORD  ValueFormat,
unsigned int  ppem,
POINT ptPlacement,
POINT ptAdvance 
)
static

Definition at line 1662 of file opentype.c.

1664{
1665 if (ValueFormat & 0x0001) ptPlacement->x += (short)ValueRecord->XPlacement;
1666 if (ValueFormat & 0x0002) ptPlacement->y += (short)ValueRecord->YPlacement;
1667 if (ValueFormat & 0x0004) ptAdvance->x += (short)ValueRecord->XAdvance;
1668 if (ValueFormat & 0x0008) ptAdvance->y += (short)ValueRecord->YAdvance;
1669 if (ValueFormat & 0x0010) ptPlacement->x += GPOS_get_device_table_value((const OT_DeviceTable*)(head + ValueRecord->XPlaDevice), ppem);
1670 if (ValueFormat & 0x0020) ptPlacement->y += GPOS_get_device_table_value((const OT_DeviceTable*)(head + ValueRecord->YPlaDevice), ppem);
1671 if (ValueFormat & 0x0040) ptAdvance->x += GPOS_get_device_table_value((const OT_DeviceTable*)(head + ValueRecord->XAdvDevice), ppem);
1672 if (ValueFormat & 0x0080) ptAdvance->y += GPOS_get_device_table_value((const OT_DeviceTable*)(head + ValueRecord->YAdvDevice), ppem);
1673 if (ValueFormat & 0xFF00) FIXME("Unhandled Value Format %x\n",ValueFormat&0xFF00);
1674}
struct outqueuenode * head
Definition: adnsresfilter.c:66
if(dx< 0)
Definition: linetemp.h:194

Referenced by apply_pair_value(), and GPOS_apply_SingleAdjustment().

◆ GSUB_apply_AlternateSubst()

static INT GSUB_apply_AlternateSubst ( const OT_LookupTable look,
WORD glyphs,
INT  glyph_index,
INT  write_dir,
INT glyph_count 
)
static

Definition at line 978 of file opentype.c.

979{
980 int j;
981 TRACE("Alternate Substitution Subtable\n");
982
983 for (j = 0; j < GET_BE_WORD(look->SubTableCount); j++)
984 {
985 int offset;
986 const GSUB_AlternateSubstFormat1 *asf1;
987 INT index;
988
989 asf1 = (const GSUB_AlternateSubstFormat1*)GSUB_get_subtable(look, j);
990 offset = GET_BE_WORD(asf1->Coverage);
991
992 index = GSUB_is_glyph_covered((const BYTE*)asf1+offset, glyphs[glyph_index]);
993 if (index != -1)
994 {
995 const GSUB_AlternateSet *as;
997 as = (const GSUB_AlternateSet*)((const BYTE*)asf1+offset);
998 FIXME("%i alternates, picking index 0\n",GET_BE_WORD(as->GlyphCount));
999 if (glyphs[glyph_index] == GET_BE_WORD(as->Alternate[0]))
1000 return GSUB_E_NOGLYPH;
1001
1002 TRACE(" Glyph 0x%x ->",glyphs[glyph_index]);
1003 glyphs[glyph_index] = GET_BE_WORD(as->Alternate[0]);
1004 TRACE(" 0x%x\n",glyphs[glyph_index]);
1005 return glyph_index + write_dir;
1006 }
1007 }
1008 return GSUB_E_NOGLYPH;
1009}
static const BYTE * GSUB_get_subtable(const OT_LookupTable *look, int index)
Definition: opentype.c:863
WORD Alternate[1]
Definition: opentype.c:383
#define GSUB_E_NOGLYPH

Referenced by GSUB_apply_lookup().

◆ GSUB_apply_ChainContextSubst()

static INT GSUB_apply_ChainContextSubst ( const OT_LookupList lookup,
const OT_LookupTable look,
WORD glyphs,
INT  glyph_index,
INT  write_dir,
INT glyph_count 
)
static

Definition at line 1245 of file opentype.c.

1246{
1247 int j;
1248
1249 TRACE("Chaining Contextual Substitution Subtable\n");
1250 for (j = 0; j < GET_BE_WORD(look->SubTableCount); j++)
1251 {
1252 const GSUB_ChainContextSubstFormat1 *ccsf1;
1253 int offset;
1254 int dirLookahead = write_dir;
1255 int dirBacktrack = -1 * write_dir;
1256
1257 ccsf1 = (const GSUB_ChainContextSubstFormat1*)GSUB_get_subtable(look, j);
1258 if (GET_BE_WORD(ccsf1->SubstFormat) == 1)
1259 {
1260 static int once;
1261 if (!once++)
1262 FIXME(" TODO: subtype 1 (Simple context glyph substitution)\n");
1263 continue;
1264 }
1265 else if (GET_BE_WORD(ccsf1->SubstFormat) == 2)
1266 {
1267 WORD offset, count;
1268 const void *backtrack_class_table;
1269 const void *input_class_table;
1270 const void *lookahead_class_table;
1271 int i;
1272 WORD class;
1273
1275 const GSUB_ChainSubClassSet *csc;
1276
1277 TRACE(" subtype 2 (Class-based Chaining Context Glyph Substitution)\n");
1278
1279 offset = GET_BE_WORD(ccsf2->Coverage);
1280
1281 if (GSUB_is_glyph_covered((const BYTE*)ccsf2+offset, glyphs[glyph_index]) == -1)
1282 {
1283 TRACE("Glyph not covered\n");
1284 continue;
1285 }
1287 backtrack_class_table = (const BYTE*)ccsf2+offset;
1289 input_class_table = (const BYTE*)ccsf2+offset;
1291 lookahead_class_table = (const BYTE*)ccsf2+offset;
1293
1294 class = OT_get_glyph_class(input_class_table, glyphs[glyph_index]);
1295 offset = GET_BE_WORD(ccsf2->ChainSubClassSet[class]);
1296
1297 if (offset == 0)
1298 {
1299 TRACE("No rules for class\n");
1300 continue;
1301 }
1302
1303 csc = (const GSUB_ChainSubClassSet*)((BYTE*)ccsf2+offset);
1305
1306 TRACE("%i rules to check\n",count);
1307
1308 for (i = 0; i < count; i++)
1309 {
1310 WORD backtrack_count, input_count, lookahead_count, substitute_count;
1311 int k;
1312 const GSUB_ChainSubClassRule_1 *backtrack;
1314 const GSUB_ChainSubClassRule_3 *lookahead;
1315 const GSUB_ChainSubClassRule_4 *substitute;
1316 int new_index = GSUB_E_NOGLYPH;
1317
1319 backtrack = (const GSUB_ChainSubClassRule_1 *)((BYTE *)csc + offset);
1320 backtrack_count = GET_BE_WORD(backtrack->BacktrackGlyphCount);
1321 k = glyph_index + dirBacktrack * backtrack_count;
1322 if (k < 0 || k >= *glyph_count)
1323 continue;
1324
1325 input = (const GSUB_ChainSubClassRule_2 *)&backtrack->Backtrack[backtrack_count];
1326 input_count = GET_BE_WORD(input->InputGlyphCount) - 1;
1327 k = glyph_index + write_dir * input_count;
1328 if (k < 0 || k >= *glyph_count)
1329 continue;
1330
1331 lookahead = (const GSUB_ChainSubClassRule_3 *)&input->Input[input_count];
1332 lookahead_count = GET_BE_WORD(lookahead->LookaheadGlyphCount);
1333 k = glyph_index + dirLookahead * (input_count + lookahead_count);
1334 if (k < 0 || k >= *glyph_count)
1335 continue;
1336
1337 substitute = (const GSUB_ChainSubClassRule_4 *)&lookahead->LookAhead[lookahead_count];
1338
1339 for (k = 0; k < backtrack_count; ++k)
1340 {
1341 WORD target_class = GET_BE_WORD(backtrack->Backtrack[k]);
1342 WORD glyph_class = OT_get_glyph_class(backtrack_class_table, glyphs[glyph_index + (dirBacktrack * (k+1))]);
1343 if (target_class != glyph_class)
1344 break;
1345 }
1346 if (k != backtrack_count)
1347 continue;
1348 TRACE("Matched Backtrack\n");
1349
1350 for (k = 0; k < input_count; ++k)
1351 {
1352 WORD target_class = GET_BE_WORD(input->Input[k]);
1353 WORD glyph_class = OT_get_glyph_class(input_class_table, glyphs[glyph_index + (write_dir * (k+1))]);
1354 if (target_class != glyph_class)
1355 break;
1356 }
1357 if (k != input_count)
1358 continue;
1359 TRACE("Matched IndexGlyphs\n");
1360
1361 for (k = 0; k < lookahead_count; ++k)
1362 {
1363 WORD target_class = GET_BE_WORD(lookahead->LookAhead[k]);
1364 WORD glyph_class = OT_get_glyph_class(lookahead_class_table,
1365 glyphs[glyph_index + (dirLookahead * (input_count + k + 1))]);
1366 if (target_class != glyph_class)
1367 break;
1368 }
1369 if (k != lookahead_count)
1370 continue;
1371 TRACE("Matched LookAhead\n");
1372
1373 substitute_count = GET_BE_WORD(substitute->SubstCount);
1374 for (k = 0; k < substitute_count; ++k)
1375 {
1376 unsigned int lookup_index = GET_BE_WORD(substitute->SubstLookupRecord[k].LookupListIndex);
1377 unsigned int sequence_index = GET_BE_WORD(substitute->SubstLookupRecord[k].SequenceIndex);
1378 unsigned int g = glyph_index + write_dir * sequence_index;
1379
1380 if (g >= *glyph_count)
1381 {
1382 WARN("Skipping invalid sequence index %u (glyph index %u, write dir %d).\n",
1383 sequence_index, glyph_index, write_dir);
1384 continue;
1385 }
1386
1387 TRACE("SUBST: %u -> %u %u.\n", k, sequence_index, lookup_index);
1388 new_index = GSUB_apply_lookup(lookup, lookup_index, glyphs, g, write_dir, glyph_count);
1389 if (new_index == GSUB_E_NOGLYPH)
1390 ERR("Chain failed to generate a glyph.\n");
1391 }
1392 return new_index;
1393 }
1394 }
1395 else if (GET_BE_WORD(ccsf1->SubstFormat) == 3)
1396 {
1397 WORD backtrack_count, input_count, lookahead_count, substitution_count;
1398 int k;
1399 const GSUB_ChainContextSubstFormat3_1 *backtrack;
1401 const GSUB_ChainContextSubstFormat3_3 *lookahead;
1402 const GSUB_ChainContextSubstFormat3_4 *substitute;
1403 int new_index = GSUB_E_NOGLYPH;
1404
1405 TRACE(" subtype 3 (Coverage-based Chaining Context Glyph Substitution)\n");
1406
1407 backtrack = (const GSUB_ChainContextSubstFormat3_1 *)ccsf1;
1408 backtrack_count = GET_BE_WORD(backtrack->BacktrackGlyphCount);
1409 k = glyph_index + dirBacktrack * backtrack_count;
1410 if (k < 0 || k >= *glyph_count)
1411 continue;
1412
1413 input = (const GSUB_ChainContextSubstFormat3_2 *)&backtrack->Coverage[backtrack_count];
1414 input_count = GET_BE_WORD(input->InputGlyphCount);
1415 k = glyph_index + write_dir * (input_count - 1);
1416 if (k < 0 || k >= *glyph_count)
1417 continue;
1418
1419 lookahead = (const GSUB_ChainContextSubstFormat3_3 *)&input->Coverage[input_count];
1420 lookahead_count = GET_BE_WORD(lookahead->LookaheadGlyphCount);
1421 k = glyph_index + dirLookahead * (input_count + lookahead_count - 1);
1422 if (k < 0 || k >= *glyph_count)
1423 continue;
1424
1425 substitute = (const GSUB_ChainContextSubstFormat3_4 *)&lookahead->Coverage[lookahead_count];
1426
1427 for (k = 0; k < backtrack_count; ++k)
1428 {
1429 offset = GET_BE_WORD(backtrack->Coverage[k]);
1430 if (GSUB_is_glyph_covered((const BYTE *)ccsf1 + offset,
1431 glyphs[glyph_index + (dirBacktrack * (k + 1))]) == -1)
1432 break;
1433 }
1434 if (k != backtrack_count)
1435 continue;
1436 TRACE("Matched Backtrack\n");
1437
1438 for (k = 0; k < input_count; ++k)
1439 {
1440 offset = GET_BE_WORD(input->Coverage[k]);
1441 if (GSUB_is_glyph_covered((const BYTE *)ccsf1 + offset,
1442 glyphs[glyph_index + (write_dir * k)]) == -1)
1443 break;
1444 }
1445 if (k != input_count)
1446 continue;
1447 TRACE("Matched IndexGlyphs\n");
1448
1449 for (k = 0; k < lookahead_count; ++k)
1450 {
1451 offset = GET_BE_WORD(lookahead->Coverage[k]);
1452 if (GSUB_is_glyph_covered((const BYTE *)ccsf1 + offset,
1453 glyphs[glyph_index + (dirLookahead * (input_count + k))]) == -1)
1454 break;
1455 }
1456 if (k != lookahead_count)
1457 continue;
1458 TRACE("Matched LookAhead\n");
1459
1460 substitution_count = GET_BE_WORD(substitute->SubstCount);
1461 for (k = 0; k < substitution_count; ++k)
1462 {
1463 unsigned int lookup_index = GET_BE_WORD(substitute->SubstLookupRecord[k].LookupListIndex);
1464 unsigned int sequence_index = GET_BE_WORD(substitute->SubstLookupRecord[k].SequenceIndex);
1465 unsigned int g = glyph_index + write_dir * sequence_index;
1466
1467 if (g >= *glyph_count)
1468 {
1469 WARN("Skipping invalid sequence index %u (glyph index %u, write dir %d).\n",
1470 sequence_index, glyph_index, write_dir);
1471 continue;
1472 }
1473
1474 TRACE("SUBST: %u -> %u %u.\n", k, sequence_index, lookup_index);
1475 new_index = GSUB_apply_lookup(lookup, lookup_index, glyphs, g, write_dir, glyph_count);
1476 if (new_index == GSUB_E_NOGLYPH)
1477 ERR("Chain failed to generate a glyph.\n");
1478 }
1479 return new_index;
1480 }
1481 }
1482 return GSUB_E_NOGLYPH;
1483}
static INT GSUB_apply_lookup(const OT_LookupList *lookup, INT lookup_index, WORD *glyphs, INT glyph_index, INT write_dir, INT *glyph_count)
Definition: opentype.c:1485
GSUB_SubstLookupRecord SubstLookupRecord[1]
Definition: opentype.c:371
GSUB_SubstLookupRecord SubstLookupRecord[1]
Definition: opentype.c:350
WORD ChainSubClassRule[1]
Definition: opentype.c:330

Referenced by GSUB_apply_lookup().

◆ GSUB_apply_ContextSubst()

static INT GSUB_apply_ContextSubst ( const OT_LookupList lookup,
const OT_LookupTable look,
WORD glyphs,
INT  glyph_index,
INT  write_dir,
INT glyph_count 
)
static

Definition at line 1074 of file opentype.c.

1075{
1076 int j;
1077 TRACE("Context Substitution Subtable\n");
1078 for (j = 0; j < GET_BE_WORD(look->SubTableCount); j++)
1079 {
1080 const GSUB_ContextSubstFormat1 *csf1;
1081
1082 csf1 = (const GSUB_ContextSubstFormat1*)GSUB_get_subtable(look, j);
1083 if (GET_BE_WORD(csf1->SubstFormat) == 1)
1084 {
1085 int offset, index;
1086 TRACE("Context Substitution Subtable: Class 1\n");
1087 offset = GET_BE_WORD(csf1->Coverage);
1088 index = GSUB_is_glyph_covered((const BYTE*)csf1+offset, glyphs[glyph_index]);
1089 TRACE(" Coverage index %i\n",index);
1090 if (index != -1)
1091 {
1092 int k, count;
1093 const GSUB_SubRuleSet *srs;
1095 srs = (const GSUB_SubRuleSet*)((const BYTE*)csf1+offset);
1097 TRACE(" SubRuleSet has %i members\n",count);
1098 for (k = 0; k < count; k++)
1099 {
1100 const GSUB_SubRule_1 *sr;
1101 const GSUB_SubRule_2 *sr_2;
1102 unsigned int g;
1103 int g_count, l;
1104 int newIndex = glyph_index;
1105
1106 offset = GET_BE_WORD(srs->SubRule[k]);
1107 sr = (const GSUB_SubRule_1*)((const BYTE*)srs+offset);
1108 g_count = GET_BE_WORD(sr->GlyphCount);
1109 TRACE(" SubRule has %i glyphs\n",g_count);
1110
1111 g = glyph_index + write_dir * (g_count - 1);
1112 if (g >= *glyph_count)
1113 continue;
1114
1115 for (l = 0; l < g_count-1; l++)
1116 if (glyphs[glyph_index + (write_dir * (l+1))] != GET_BE_WORD(sr->Input[l])) break;
1117
1118 if (l < g_count-1)
1119 {
1120 TRACE(" Rule does not match\n");
1121 continue;
1122 }
1123
1124 TRACE(" Rule matches\n");
1125 sr_2 = (const GSUB_SubRule_2 *)&sr->Input[g_count - 1];
1126
1127 for (l = 0; l < GET_BE_WORD(sr->SubstCount); l++)
1128 {
1129 unsigned int lookup_index = GET_BE_WORD(sr_2->SubstLookupRecord[l].LookupListIndex);
1130 unsigned int sequence_index = GET_BE_WORD(sr_2->SubstLookupRecord[l].SequenceIndex);
1131
1132 g = glyph_index + write_dir * sequence_index;
1133 if (g >= *glyph_count)
1134 {
1135 WARN("Invalid sequence index %u (glyph index %u, write dir %d).\n",
1136 sequence_index, glyph_index, write_dir);
1137 continue;
1138 }
1139
1140 TRACE(" SUBST: %u -> %u %u.\n", l, sequence_index, lookup_index);
1141 newIndex = GSUB_apply_lookup(lookup, lookup_index, glyphs, g, write_dir, glyph_count);
1142 if (newIndex == GSUB_E_NOGLYPH)
1143 {
1144 ERR(" Chain failed to generate a glyph\n");
1145 continue;
1146 }
1147 }
1148 return newIndex;
1149 }
1150 }
1151 }
1152 else if (GET_BE_WORD(csf1->SubstFormat) == 2)
1153 {
1154 const GSUB_ContextSubstFormat2 *csf2;
1155 const void *glyph_class_table;
1156 int offset, index;
1157
1158 csf2 = (const GSUB_ContextSubstFormat2*)csf1;
1159 TRACE("Context Substitution Subtable: Class 2\n");
1160 offset = GET_BE_WORD(csf2->Coverage);
1161 index = GSUB_is_glyph_covered((const BYTE*)csf2+offset, glyphs[glyph_index]);
1162 TRACE(" Coverage index %i\n",index);
1163 if (index != -1)
1164 {
1165 int k, count, class;
1166 const GSUB_SubClassSet *scs;
1167
1168 offset = GET_BE_WORD(csf2->ClassDef);
1169 glyph_class_table = (const BYTE *)csf2 + offset;
1170
1171 class = OT_get_glyph_class(glyph_class_table,glyphs[glyph_index]);
1172
1173 offset = GET_BE_WORD(csf2->SubClassSet[class]);
1174 if (offset == 0)
1175 {
1176 TRACE(" No class rule table for class %i\n",class);
1177 continue;
1178 }
1179 scs = (const GSUB_SubClassSet*)((const BYTE*)csf2+offset);
1181 TRACE(" SubClassSet has %i members\n",count);
1182 for (k = 0; k < count; k++)
1183 {
1184 const GSUB_SubClassRule_1 *sr;
1185 const GSUB_SubClassRule_2 *sr_2;
1186 unsigned int g;
1187 int g_count, l;
1188 int newIndex = glyph_index;
1189
1191 sr = (const GSUB_SubClassRule_1*)((const BYTE*)scs+offset);
1192 g_count = GET_BE_WORD(sr->GlyphCount);
1193 TRACE(" SubClassRule has %i glyphs classes\n",g_count);
1194
1195 g = glyph_index + write_dir * (g_count - 1);
1196 if (g >= *glyph_count)
1197 continue;
1198
1199 for (l = 0; l < g_count-1; l++)
1200 {
1201 int g_class = OT_get_glyph_class(glyph_class_table, glyphs[glyph_index + (write_dir * (l+1))]);
1202 if (g_class != GET_BE_WORD(sr->Class[l])) break;
1203 }
1204
1205 if (l < g_count-1)
1206 {
1207 TRACE(" Rule does not match\n");
1208 continue;
1209 }
1210
1211 TRACE(" Rule matches\n");
1212 sr_2 = (const GSUB_SubClassRule_2 *)&sr->Class[g_count - 1];
1213
1214 for (l = 0; l < GET_BE_WORD(sr->SubstCount); l++)
1215 {
1216 unsigned int lookup_index = GET_BE_WORD(sr_2->SubstLookupRecord[l].LookupListIndex);
1217 unsigned int sequence_index = GET_BE_WORD(sr_2->SubstLookupRecord[l].SequenceIndex);
1218
1219 g = glyph_index + write_dir * sequence_index;
1220 if (g >= *glyph_count)
1221 {
1222 WARN("Invalid sequence index %u (glyph index %u, write dir %d).\n",
1223 sequence_index, glyph_index, write_dir);
1224 continue;
1225 }
1226
1227 TRACE(" SUBST: %u -> %u %u.\n", l, sequence_index, lookup_index);
1228 newIndex = GSUB_apply_lookup(lookup, lookup_index, glyphs, g, write_dir, glyph_count);
1229 if (newIndex == GSUB_E_NOGLYPH)
1230 {
1231 ERR(" Chain failed to generate a glyph\n");
1232 continue;
1233 }
1234 }
1235 return newIndex;
1236 }
1237 }
1238 }
1239 else
1240 FIXME("Unhandled Context Substitution Format %i\n", GET_BE_WORD(csf1->SubstFormat));
1241 }
1242 return GSUB_E_NOGLYPH;
1243}
GSUB_SubstLookupRecord SubstLookupRecord[1]
Definition: opentype.c:308
WORD SubClassRuleCnt
Definition: opentype.c:297
WORD SubClassRule[1]
Definition: opentype.c:298
WORD SubRule[1]
Definition: opentype.c:275
WORD SubRuleCount
Definition: opentype.c:274
WORD SubstCount
Definition: opentype.c:280
WORD Input[1]
Definition: opentype.c:281
WORD GlyphCount
Definition: opentype.c:279
GSUB_SubstLookupRecord SubstLookupRecord[1]
Definition: opentype.c:285

Referenced by GSUB_apply_lookup().

◆ GSUB_apply_LigatureSubst()

static INT GSUB_apply_LigatureSubst ( const OT_LookupTable look,
WORD glyphs,
INT  glyph_index,
INT  write_dir,
INT glyph_count 
)
static

Definition at line 1011 of file opentype.c.

1012{
1013 int j;
1014
1015 TRACE("Ligature Substitution Subtable\n");
1016 for (j = 0; j < GET_BE_WORD(look->SubTableCount); j++)
1017 {
1018 const GSUB_LigatureSubstFormat1 *lsf1;
1019 int offset,index;
1020
1021 lsf1 = (const GSUB_LigatureSubstFormat1*)GSUB_get_subtable(look, j);
1022 offset = GET_BE_WORD(lsf1->Coverage);
1023 index = GSUB_is_glyph_covered((const BYTE*)lsf1+offset, glyphs[glyph_index]);
1024 TRACE(" Coverage index %i\n",index);
1025 if (index != -1)
1026 {
1027 const GSUB_LigatureSet *ls;
1028 int k, count;
1029
1031 ls = (const GSUB_LigatureSet*)((const BYTE*)lsf1+offset);
1032 count = GET_BE_WORD(ls->LigatureCount);
1033 TRACE(" LigatureSet has %i members\n",count);
1034 for (k = 0; k < count; k++)
1035 {
1036 const GSUB_Ligature *lig;
1037 int CompCount,l,CompIndex;
1038
1039 offset = GET_BE_WORD(ls->Ligature[k]);
1040 lig = (const GSUB_Ligature*)((const BYTE*)ls+offset);
1041 CompCount = GET_BE_WORD(lig->CompCount) - 1;
1042 CompIndex = glyph_index+write_dir;
1043 for (l = 0; l < CompCount && CompIndex >= 0 && CompIndex < *glyph_count; l++)
1044 {
1045 int CompGlyph;
1046 CompGlyph = GET_BE_WORD(lig->Component[l]);
1047 if (CompGlyph != glyphs[CompIndex])
1048 break;
1049 CompIndex += write_dir;
1050 }
1051 if (l == CompCount)
1052 {
1053 int replaceIdx = glyph_index;
1054 if (write_dir < 0)
1055 replaceIdx = glyph_index - CompCount;
1056
1057 TRACE(" Glyph is 0x%x (+%i) ->",glyphs[glyph_index],CompCount);
1058 glyphs[replaceIdx] = GET_BE_WORD(lig->LigGlyph);
1059 TRACE("0x%x\n",glyphs[replaceIdx]);
1060 if (CompCount > 0)
1061 {
1062 unsigned int j = replaceIdx + 1;
1063 memmove(&glyphs[j], &glyphs[j + CompCount], (*glyph_count - j) * sizeof(*glyphs));
1064 *glyph_count = *glyph_count - CompCount;
1065 }
1066 return replaceIdx + write_dir;
1067 }
1068 }
1069 }
1070 }
1071 return GSUB_E_NOGLYPH;
1072}
void ls(int argc, const char *argv[])
Definition: cmds.c:1136
#define memmove(s1, s2, n)
Definition: mkisofs.h:881
WORD Component[1]
Definition: opentype.c:257
WORD CompCount
Definition: opentype.c:256
WORD LigGlyph
Definition: opentype.c:255

Referenced by GSUB_apply_lookup().

◆ GSUB_apply_lookup()

static INT GSUB_apply_lookup ( const OT_LookupList lookup,
INT  lookup_index,
WORD glyphs,
INT  glyph_index,
INT  write_dir,
INT glyph_count 
)
static

Definition at line 1485 of file opentype.c.

1486{
1487 int offset;
1489 const OT_LookupTable *look;
1490
1491 offset = GET_BE_WORD(lookup->Lookup[lookup_index]);
1492 look = (const OT_LookupTable*)((const BYTE*)lookup + offset);
1493 type = GET_BE_WORD(look->LookupType);
1494 TRACE("type %#x, flag %#x, subtables %u.\n", type,
1496
1498 {
1499 if (GET_BE_WORD(look->SubTableCount))
1500 {
1501 const GSUB_ExtensionPosFormat1 *ext = (const GSUB_ExtensionPosFormat1 *)((const BYTE *)look + GET_BE_WORD(look->SubTable[0]));
1502 if (GET_BE_WORD(ext->SubstFormat) == 1)
1503 {
1504 type = GET_BE_WORD(ext->ExtensionLookupType);
1505 TRACE("extension type %i\n",type);
1506 }
1507 else
1508 {
1509 FIXME("Unhandled Extension Substitution Format %i\n",GET_BE_WORD(ext->SubstFormat));
1510 }
1511 }
1512 else
1513 {
1514 WARN("lookup type is Extension Substitution but no extension subtable exists\n");
1515 }
1516 }
1517 switch(type)
1518 {
1519 case GSUB_LOOKUP_SINGLE:
1520 return GSUB_apply_SingleSubst(look, glyphs, glyph_index, write_dir, glyph_count);
1522 return GSUB_apply_MultipleSubst(look, glyphs, glyph_index, write_dir, glyph_count);
1524 return GSUB_apply_AlternateSubst(look, glyphs, glyph_index, write_dir, glyph_count);
1526 return GSUB_apply_LigatureSubst(look, glyphs, glyph_index, write_dir, glyph_count);
1528 return GSUB_apply_ContextSubst(lookup, look, glyphs, glyph_index, write_dir, glyph_count);
1530 return GSUB_apply_ChainContextSubst(lookup, look, glyphs, glyph_index, write_dir, glyph_count);
1532 FIXME("Extension Substitution types not valid here\n");
1533 break;
1534 default:
1535 FIXME("Unhandled GSUB lookup type %#x.\n", type);
1536 }
1537 return GSUB_E_NOGLYPH;
1538}
static INT GSUB_apply_ContextSubst(const OT_LookupList *lookup, const OT_LookupTable *look, WORD *glyphs, INT glyph_index, INT write_dir, INT *glyph_count)
Definition: opentype.c:1074
static INT GSUB_apply_ChainContextSubst(const OT_LookupList *lookup, const OT_LookupTable *look, WORD *glyphs, INT glyph_index, INT write_dir, INT *glyph_count)
Definition: opentype.c:1245
static INT GSUB_apply_LigatureSubst(const OT_LookupTable *look, WORD *glyphs, INT glyph_index, INT write_dir, INT *glyph_count)
Definition: opentype.c:1011
static INT GSUB_apply_SingleSubst(const OT_LookupTable *look, WORD *glyphs, INT glyph_index, INT write_dir, INT *glyph_count)
Definition: opentype.c:882
gsub_lookup_type
Definition: opentype.c:66
static INT GSUB_apply_MultipleSubst(const OT_LookupTable *look, WORD *glyphs, INT glyph_index, INT write_dir, INT *glyph_count)
Definition: opentype.c:928
static INT GSUB_apply_AlternateSubst(const OT_LookupTable *look, WORD *glyphs, INT glyph_index, INT write_dir, INT *glyph_count)
Definition: opentype.c:978

Referenced by GSUB_apply_ChainContextSubst(), GSUB_apply_ContextSubst(), and OpenType_apply_GSUB_lookup().

◆ GSUB_apply_MultipleSubst()

static INT GSUB_apply_MultipleSubst ( const OT_LookupTable look,
WORD glyphs,
INT  glyph_index,
INT  write_dir,
INT glyph_count 
)
static

Definition at line 928 of file opentype.c.

929{
930 int j;
931 TRACE("Multiple Substitution Subtable\n");
932
933 for (j = 0; j < GET_BE_WORD(look->SubTableCount); j++)
934 {
935 int offset, index;
936 const GSUB_MultipleSubstFormat1 *msf1;
937 msf1 = (const GSUB_MultipleSubstFormat1*)GSUB_get_subtable(look, j);
938
939 offset = GET_BE_WORD(msf1->Coverage);
940 index = GSUB_is_glyph_covered((const BYTE*)msf1+offset, glyphs[glyph_index]);
941 if (index != -1)
942 {
943 const GSUB_Sequence *seq;
944 int sub_count;
945 int j;
947 seq = (const GSUB_Sequence*)((const BYTE*)msf1+offset);
948 sub_count = GET_BE_WORD(seq->GlyphCount);
949 TRACE(" Glyph 0x%x (+%i)->",glyphs[glyph_index],(sub_count-1));
950
951 for (j = (*glyph_count)+(sub_count-1); j > glyph_index; j--)
952 glyphs[j] =glyphs[j-(sub_count-1)];
953
954 for (j = 0; j < sub_count; j++)
955 if (write_dir < 0)
956 glyphs[glyph_index + (sub_count-1) - j] = GET_BE_WORD(seq->Substitute[j]);
957 else
958 glyphs[glyph_index + j] = GET_BE_WORD(seq->Substitute[j]);
959
960 *glyph_count = *glyph_count + (sub_count - 1);
961
962 if (TRACE_ON(uniscribe))
963 {
964 for (j = 0; j < sub_count; j++)
965 TRACE(" 0x%x",glyphs[glyph_index+j]);
966 TRACE("\n");
967 }
968
969 if (write_dir > 0)
970 return glyph_index + sub_count;
971 else
972 return glyph_index - 1;
973 }
974 }
975 return GSUB_E_NOGLYPH;
976}
#define TRACE_ON(x)
Definition: compat.h:75
WORD Substitute[1]
Definition: opentype.c:239
WORD GlyphCount
Definition: opentype.c:238

Referenced by GSUB_apply_lookup().

◆ GSUB_apply_SingleSubst()

static INT GSUB_apply_SingleSubst ( const OT_LookupTable look,
WORD glyphs,
INT  glyph_index,
INT  write_dir,
INT glyph_count 
)
static

Definition at line 882 of file opentype.c.

883{
884 int j;
885 TRACE("Single Substitution Subtable\n");
886
887 for (j = 0; j < GET_BE_WORD(look->SubTableCount); j++)
888 {
890 if (GET_BE_WORD(ssf1->SubstFormat) == 1)
891 {
892 int offset = GET_BE_WORD(ssf1->Coverage);
893 TRACE(" subtype 1, delta %i\n", GET_BE_WORD(ssf1->DeltaGlyphID));
894 if (GSUB_is_glyph_covered((const BYTE*)ssf1+offset, glyphs[glyph_index]) != -1)
895 {
896 TRACE(" Glyph 0x%x ->",glyphs[glyph_index]);
897 glyphs[glyph_index] = glyphs[glyph_index] + GET_BE_WORD(ssf1->DeltaGlyphID);
898 TRACE(" 0x%x\n",glyphs[glyph_index]);
899 return glyph_index + write_dir;
900 }
901 }
902 else
903 {
904 const GSUB_SingleSubstFormat2 *ssf2;
905 INT index;
906 INT offset;
907
908 ssf2 = (const GSUB_SingleSubstFormat2 *)ssf1;
909 offset = GET_BE_WORD(ssf1->Coverage);
910 TRACE(" subtype 2, glyph count %i\n", GET_BE_WORD(ssf2->GlyphCount));
911 index = GSUB_is_glyph_covered((const BYTE*)ssf2+offset, glyphs[glyph_index]);
912 TRACE(" Coverage index %i\n",index);
913 if (index != -1)
914 {
915 if (glyphs[glyph_index] == GET_BE_WORD(ssf2->Substitute[index]))
916 return GSUB_E_NOGLYPH;
917
918 TRACE(" Glyph is 0x%x ->",glyphs[glyph_index]);
919 glyphs[glyph_index] = GET_BE_WORD(ssf2->Substitute[index]);
920 TRACE("0x%x\n",glyphs[glyph_index]);
921 return glyph_index + write_dir;
922 }
923 }
924 }
925 return GSUB_E_NOGLYPH;
926}

Referenced by GSUB_apply_lookup().

◆ GSUB_get_subtable()

static const BYTE * GSUB_get_subtable ( const OT_LookupTable look,
int  index 
)
static

Definition at line 863 of file opentype.c.

864{
865 int offset = GET_BE_WORD(look->SubTable[index]);
866
868 {
869 const GSUB_ExtensionPosFormat1 *ext = (const GSUB_ExtensionPosFormat1 *)((const BYTE *)look + offset);
870 if (GET_BE_WORD(ext->SubstFormat) == 1)
871 {
872 offset += GET_BE_DWORD(ext->ExtensionOffset);
873 }
874 else
875 {
876 FIXME("Unhandled Extension Substitution Format %i\n",GET_BE_WORD(ext->SubstFormat));
877 }
878 }
879 return (const BYTE *)look + offset;
880}

Referenced by GSUB_apply_AlternateSubst(), GSUB_apply_ChainContextSubst(), GSUB_apply_ContextSubst(), GSUB_apply_LigatureSubst(), GSUB_apply_MultipleSubst(), and GSUB_apply_SingleSubst().

◆ GSUB_is_glyph_covered()

static int GSUB_is_glyph_covered ( const void table,
unsigned int  glyph 
)
static

Definition at line 819 of file opentype.c.

820{
821 const OT_CoverageFormat1* cf1;
822
823 cf1 = table;
824
825 if (GET_BE_WORD(cf1->CoverageFormat) == 1)
826 {
827 int count = GET_BE_WORD(cf1->GlyphCount);
828 int i;
829 TRACE("Coverage Format 1, %i glyphs\n",count);
830 for (i = 0; i < count; i++)
831 if (glyph == GET_BE_WORD(cf1->GlyphArray[i]))
832 return i;
833 return -1;
834 }
835 else if (GET_BE_WORD(cf1->CoverageFormat) == 2)
836 {
837 const OT_CoverageFormat2* cf2;
838 int i;
839 int count;
840 cf2 = (const OT_CoverageFormat2*)cf1;
841
843 TRACE("Coverage Format 2, %i ranges\n",count);
844 for (i = 0; i < count; i++)
845 {
846 if (glyph < GET_BE_WORD(cf2->RangeRecord[i].Start))
847 return -1;
848 if ((glyph >= GET_BE_WORD(cf2->RangeRecord[i].Start)) &&
849 (glyph <= GET_BE_WORD(cf2->RangeRecord[i].End)))
850 {
852 glyph - GET_BE_WORD(cf2->RangeRecord[i].Start));
853 }
854 }
855 return -1;
856 }
857 else
858 ERR("Unknown CoverageFormat %i\n",GET_BE_WORD(cf1->CoverageFormat));
859
860 return -1;
861}
WORD GlyphArray[1]
Definition: opentype.c:202
OT_RangeRecord RangeRecord[1]
Definition: opentype.c:214
WORD StartCoverageIndex
Definition: opentype.c:208

Referenced by GPOS_apply_ChainContextPos(), GPOS_apply_ContextPos(), GPOS_apply_CursiveAttachment(), GPOS_apply_MarkToBase(), GPOS_apply_MarkToLigature(), GPOS_apply_MarkToMark(), GPOS_apply_PairAdjustment(), GPOS_apply_SingleAdjustment(), GSUB_apply_AlternateSubst(), GSUB_apply_ChainContextSubst(), GSUB_apply_ContextSubst(), GSUB_apply_LigatureSubst(), GSUB_apply_MultipleSubst(), and GSUB_apply_SingleSubst().

◆ load_CMAP_format12_table()

static VOID * load_CMAP_format12_table ( HDC  hdc,
ScriptCache psc 
)
static

Definition at line 627 of file opentype.c.

628{
629 CMAP_Header *CMAP_Table = NULL;
630 int length;
631 int i;
632
633 if (!psc->CMAP_Table)
634 {
635 length = GetFontData(hdc, CMAP_TAG , 0, NULL, 0);
636 if (length != GDI_ERROR)
637 {
638 psc->CMAP_Table = heap_alloc(length);
639 GetFontData(hdc, CMAP_TAG , 0, psc->CMAP_Table, length);
640 TRACE("Loaded cmap table of %i bytes\n",length);
641 }
642 else
643 return NULL;
644 }
645
646 CMAP_Table = psc->CMAP_Table;
647
648 for (i = 0; i < GET_BE_WORD(CMAP_Table->numTables); i++)
649 {
650 if ( (GET_BE_WORD(CMAP_Table->tables[i].platformID) == 3) &&
651 (GET_BE_WORD(CMAP_Table->tables[i].encodingID) == 10) )
652 {
654 if (GET_BE_WORD(format->format) == 12)
655 return format;
656 }
657 }
658 return NULL;
659}
static void * heap_alloc(size_t len)
Definition: appwiz.h:66
GLuint GLsizei GLsizei * length
Definition: glext.h:6040
HDC hdc
Definition: main.c:9
#define CMAP_TAG
Definition: opentype.c:50
CMAP_EncodingRecord tables[1]
Definition: opentype.c:86
WORD numTables
Definition: opentype.c:85
DWORD WINAPI GetFontData(HDC hdc, DWORD dwTable, DWORD dwOffset, LPVOID lpvBuffer, DWORD cbData)
Definition: font.c:2654
#define GDI_ERROR
Definition: wingdi.h:1309

Referenced by OpenType_CMAP_GetGlyphIndex().

◆ OpenType_apply_GPOS_lookup()

unsigned int OpenType_apply_GPOS_lookup ( const ScriptCache script_cache,
const OUTLINETEXTMETRICW otm,
const LOGFONTW logfont,
const SCRIPT_ANALYSIS analysis,
int advance,
unsigned int  lookup_index,
const WORD glyphs,
unsigned int  glyph_index,
unsigned int  glyph_count,
GOFFSET goffset 
)

Definition at line 2557 of file opentype.c.

2560{
2561 const GPOS_Header *header = (const GPOS_Header *)script_cache->GPOS_Table;
2562 const OT_LookupList *lookup = (const OT_LookupList*)((const BYTE*)header + GET_BE_WORD(header->LookupList));
2563
2564 return GPOS_apply_lookup(script_cache, otm, logfont, analysis, advance, lookup,
2565 lookup_index, glyphs, glyph_index, glyph_count, goffset);
2566}

Referenced by GPOS_apply_feature().

◆ OpenType_apply_GSUB_lookup()

int OpenType_apply_GSUB_lookup ( const void table,
unsigned int  lookup_index,
WORD glyphs,
unsigned int  glyph_index,
int  write_dir,
int glyph_count 
)

Definition at line 1540 of file opentype.c.

1542{
1543 const GSUB_Header *header = (const GSUB_Header *)table;
1544 const OT_LookupList *lookup = (const OT_LookupList*)((const BYTE*)header + GET_BE_WORD(header->LookupList));
1545
1546 return GSUB_apply_lookup(lookup, lookup_index, glyphs, glyph_index, write_dir, glyph_count);
1547}

Referenced by apply_GSUB_feature(), and GSUB_apply_feature_all_lookups().

◆ OpenType_CMAP_GetGlyphIndex()

DWORD OpenType_CMAP_GetGlyphIndex ( HDC  hdc,
ScriptCache psc,
DWORD  utf32c,
WORD glyph_index,
DWORD  flags 
)

Definition at line 673 of file opentype.c.

674{
675 /* BMP: use gdi32 for ease */
676 if (utf32c < 0x10000)
677 {
678 WCHAR ch = utf32c;
679 return GetGlyphIndicesW(hdc, &ch, 1, glyph_index, flags);
680 }
681
682 if (!psc->CMAP_format12_Table)
683 psc->CMAP_format12_Table = load_CMAP_format12_table(hdc, psc);
684
686 *glyph_index = 0xffffu;
687 else
688 *glyph_index = 0u;
689
690 if (psc->CMAP_format12_Table)
691 {
694
695 format = (CMAP_SegmentedCoverage *)psc->CMAP_format12_Table;
696
697 group = bsearch(&utf32c, format->groups, GET_BE_DWORD(format->nGroups),
699
700 if (group)
701 {
702 DWORD offset = utf32c - GET_BE_DWORD(group->startCharCode);
703 *glyph_index = GET_BE_DWORD(group->startGlyphID) + offset;
704 return 0;
705 }
706 }
707 return 0;
708}
GLbitfield flags
Definition: glext.h:7161
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 * u
Definition: glfuncs.h:240
static VOID * load_CMAP_format12_table(HDC hdc, ScriptCache *psc)
Definition: opentype.c:627
static int __cdecl compare_group(const void *a, const void *b)
Definition: opentype.c:661
#define bsearch
DWORD WINAPI GetGlyphIndicesW(_In_ HDC hdc, _In_reads_(c) LPCWSTR lpstr, _In_ int c, _Out_writes_(c) LPWORD pgi, _In_ DWORD fl)
#define GGI_MARK_NONEXISTING_GLYPHS
Definition: wingdi.h:1085
__wchar_t WCHAR
Definition: xmlstorage.h:180

Referenced by ScriptShapeOpenType().

◆ OpenType_GDEF_UpdateGlyphProps()

void OpenType_GDEF_UpdateGlyphProps ( ScriptCache psc,
const WORD pwGlyphs,
const WORD  cGlyphs,
WORD pwLogClust,
const WORD  cChars,
SCRIPT_GLYPHPROP pGlyphProp 
)

Definition at line 751 of file opentype.c.

752{
753 int i;
754 void *glyph_class_table = NULL;
755
756 if (psc->GDEF_Table)
757 {
758 const GDEF_Header *header = psc->GDEF_Table;
759 WORD offset = GET_BE_WORD( header->GlyphClassDef );
760 if (offset)
761 glyph_class_table = (BYTE *)psc->GDEF_Table + offset;
762 }
763
764 for (i = 0; i < cGlyphs; i++)
765 {
766 WORD class;
767 int char_count = 0;
768 int k;
769
771 if (k >= 0)
772 {
773 for (; k < cChars && pwLogClust[k] == i; k++)
774 char_count++;
775 }
776
777 class = OT_get_glyph_class( glyph_class_table, pwGlyphs[i] );
778
779 switch (class)
780 {
781 case 0:
782 case BaseGlyph:
783 pGlyphProp[i].sva.fClusterStart = 1;
784 pGlyphProp[i].sva.fDiacritic = 0;
785 pGlyphProp[i].sva.fZeroWidth = 0;
786 break;
787 case LigatureGlyph:
788 pGlyphProp[i].sva.fClusterStart = 1;
789 pGlyphProp[i].sva.fDiacritic = 0;
790 pGlyphProp[i].sva.fZeroWidth = 0;
791 break;
792 case MarkGlyph:
793 pGlyphProp[i].sva.fClusterStart = 0;
794 pGlyphProp[i].sva.fDiacritic = 1;
795 pGlyphProp[i].sva.fZeroWidth = 1;
796 break;
797 case ComponentGlyph:
798 pGlyphProp[i].sva.fClusterStart = 0;
799 pGlyphProp[i].sva.fDiacritic = 0;
800 pGlyphProp[i].sva.fZeroWidth = 0;
801 break;
802 default:
803 ERR("Unknown glyph class %i\n",class);
804 pGlyphProp[i].sva.fClusterStart = 1;
805 pGlyphProp[i].sva.fDiacritic = 0;
806 pGlyphProp[i].sva.fZeroWidth = 0;
807 }
808
809 if (char_count == 0)
810 pGlyphProp[i].sva.fClusterStart = 0;
811 }
812}
int USP10_FindGlyphInLogClust(const WORD *pwLogClust, int cChars, WORD target)
Definition: usp10.c:1044
static SCRIPT_CACHE SCRIPT_ANALYSIS OPENTYPE_TAG OPENTYPE_TAG int TEXTRANGE_PROPERTIES int const WCHAR int cChars
Definition: usp10.c:64
static SCRIPT_CACHE SCRIPT_ANALYSIS OPENTYPE_TAG OPENTYPE_TAG int TEXTRANGE_PROPERTIES int const WCHAR int int WORD * pwLogClust
Definition: usp10.c:64
SCRIPT_VISATTR sva
Definition: usp10.h:215
WORD fClusterStart
Definition: usp10.h:179
_In_ FONTOBJ _In_ ULONG _In_ ULONG cGlyphs
Definition: winddi.h:3799

Referenced by ShapeCharGlyphProp_Arabic(), ShapeCharGlyphProp_BaseIndic(), ShapeCharGlyphProp_Default(), ShapeCharGlyphProp_Hebrew(), ShapeCharGlyphProp_None(), ShapeCharGlyphProp_Thai(), and ShapeCharGlyphProp_Tibet().

◆ OpenType_GetFontFeatureTags()

HRESULT OpenType_GetFontFeatureTags ( ScriptCache psc,
OPENTYPE_TAG  script_tag,
OPENTYPE_TAG  language_tag,
BOOL  filtered,
OPENTYPE_TAG  searchingFor,
char  tableType,
int  cMaxTags,
OPENTYPE_TAG pFeatureTags,
int pcTags,
LoadedFeature **  feature 
)

Definition at line 2872 of file opentype.c.

2873{
2874 int i;
2875 LoadedLanguage *language;
2877 HRESULT rc = S_OK;
2878
2880 if (!(script = usp10_script_cache_get_script(psc, script_tag)))
2881 {
2882 *pcTags = 0;
2883 if (!filtered)
2884 return S_OK;
2885 else
2886 return E_INVALIDARG;
2887 }
2888
2890
2891 language = &script->default_language;
2892 if (language->tag != language_tag || (!language->table[USP10_LANGUAGE_TABLE_GSUB]
2893 && !language->table[USP10_LANGUAGE_TABLE_GPOS]))
2894 language = usp10_script_get_language(script, language_tag);
2895
2896 if (!language)
2897 {
2898 *pcTags = 0;
2899 return S_OK;
2900 }
2901
2902 _initialize_feature_cache(psc, language);
2903
2904 if (tableType)
2905 {
2906 *pcTags = 0;
2907 for (i = 0; i < language->feature_count; i++)
2908 if (language->features[i].tableType == tableType)
2909 *pcTags = (*pcTags)+1;
2910 }
2911 else
2912 *pcTags = language->feature_count;
2913
2914 if (!searchingFor && cMaxTags < *pcTags)
2915 rc = E_OUTOFMEMORY;
2916 else if (searchingFor)
2917 rc = E_INVALIDARG;
2918
2919 for (i = 0; i < language->feature_count; i++)
2920 {
2921 if (i < cMaxTags)
2922 {
2923 if (!tableType || language->features[i].tableType == tableType)
2924 pFeatureTags[i] = language->features[i].tag;
2925 }
2926
2927 if (searchingFor)
2928 {
2929 if ((searchingFor == language->features[i].tag) &&
2930 (!tableType || language->features[i].tableType == tableType))
2931 {
2932 pFeatureTags[0] = language->features[i].tag;
2933 *pcTags = 1;
2934 if (feature)
2935 *feature = &language->features[i];
2936 rc = S_OK;
2937 break;
2938 }
2939 }
2940 }
2941 return rc;
2942}
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
#define E_INVALIDARG
Definition: ddrawi.h:101
#define S_OK
Definition: intsafe.h:52
INTERNETFEATURELIST feature
Definition: misc.c:1719
static SCRIPT_CACHE SCRIPT_ANALYSIS OPENTYPE_TAG OPENTYPE_TAG int OPENTYPE_TAG * pFeatureTags
Definition: usp10.c:68
static SCRIPT_CACHE SCRIPT_ANALYSIS int cMaxTags
Definition: usp10.c:66
static SCRIPT_CACHE SCRIPT_ANALYSIS int OPENTYPE_TAG int * pcTags
Definition: usp10.c:66
static void _initialize_script_cache(ScriptCache *script_cache)
Definition: opentype.c:2628
static void _initialize_language_cache(LoadedScript *script)
Definition: opentype.c:2746
static LoadedScript * usp10_script_cache_get_script(ScriptCache *script_cache, OPENTYPE_TAG tag)
Definition: opentype.c:2585
static void _initialize_feature_cache(ScriptCache *psc, LoadedLanguage *language)
Definition: opentype.c:2847
static LoadedLanguage * usp10_script_get_language(LoadedScript *script, OPENTYPE_TAG tag)
Definition: opentype.c:2695
OPENTYPE_TAG tag
OPENTYPE_TAG tag
LoadedFeature * features

Referenced by load_OT_feature(), and SHAPE_GetFontFeatureTags().

◆ OpenType_GetFontLanguageTags()

HRESULT OpenType_GetFontLanguageTags ( ScriptCache psc,
OPENTYPE_TAG  script_tag,
OPENTYPE_TAG  searchingFor,
int  cMaxTags,
OPENTYPE_TAG pLanguageTags,
int pcTags 
)

Definition at line 2761 of file opentype.c.

2762{
2763 int i;
2764 HRESULT rc = S_OK;
2766
2768 if (!(script = usp10_script_cache_get_script(psc, script_tag)))
2769 return E_INVALIDARG;
2770
2772
2773 if (!searchingFor && cMaxTags < script->language_count)
2774 rc = E_OUTOFMEMORY;
2775 else if (searchingFor)
2776 rc = E_INVALIDARG;
2777
2778 *pcTags = script->language_count;
2779
2780 for (i = 0; i < script->language_count; i++)
2781 {
2782 if (i < cMaxTags)
2783 pLanguageTags[i] = script->languages[i].tag;
2784
2785 if (searchingFor)
2786 {
2787 if (searchingFor == script->languages[i].tag)
2788 {
2789 pLanguageTags[0] = script->languages[i].tag;
2790 *pcTags = 1;
2791 rc = S_OK;
2792 break;
2793 }
2794 }
2795 }
2796
2797 if (script->default_language.table[USP10_LANGUAGE_TABLE_GSUB])
2798 {
2799 if (i < cMaxTags)
2800 pLanguageTags[i] = script->default_language.tag;
2801
2802 if (searchingFor && FAILED(rc))
2803 {
2804 pLanguageTags[0] = script->default_language.tag;
2805 }
2806 i++;
2807 *pcTags = (*pcTags) + 1;
2808 }
2809
2810 return rc;
2811}
#define FAILED(hr)
Definition: intsafe.h:51

Referenced by SHAPE_GetFontLanguageTags().

◆ OpenType_GetFontScriptTags()

HRESULT OpenType_GetFontScriptTags ( ScriptCache psc,
OPENTYPE_TAG  searchingFor,
int  cMaxTags,
OPENTYPE_TAG pScriptTags,
int pcTags 
)

Definition at line 2647 of file opentype.c.

2648{
2649 int i;
2650 const LoadedScript *script;
2651 HRESULT rc = S_OK;
2652
2654
2655 *pcTags = psc->script_count;
2656
2657 if (searchingFor)
2658 {
2659 if (!(script = usp10_script_cache_get_script(psc, searchingFor)))
2661
2662 *pScriptTags = script->tag;
2663 *pcTags = 1;
2664 return S_OK;
2665 }
2666
2667 if (cMaxTags < *pcTags)
2668 rc = E_OUTOFMEMORY;
2669
2670 cMaxTags = min(cMaxTags, psc->script_count);
2671 for (i = 0; i < cMaxTags; ++i)
2672 {
2673 pScriptTags[i] = psc->scripts[i].tag;
2674 }
2675 return rc;
2676}
static int int const SCRIPT_CONTROL const SCRIPT_STATE SCRIPT_ITEM ULONG * pScriptTags
Definition: usp10.c:62
#define min(a, b)
Definition: monoChain.cc:55
#define USP_E_SCRIPT_NOT_IN_FONT
Definition: usp10.h:71

Referenced by get_GSUB_Indic2(), and SHAPE_GetFontScriptTags().

◆ OT_get_glyph_class()

static WORD OT_get_glyph_class ( const void table,
WORD  glyph 
)
static

Definition at line 714 of file opentype.c.

715{
716 WORD class = 0;
717 const OT_ClassDefFormat1 *cf1 = table;
718
719 if (!table) return 0;
720
721 if (GET_BE_WORD(cf1->ClassFormat) == 1)
722 {
723 if (glyph >= GET_BE_WORD(cf1->StartGlyph))
724 {
725 int index = glyph - GET_BE_WORD(cf1->StartGlyph);
726 if (index < GET_BE_WORD(cf1->GlyphCount))
727 class = GET_BE_WORD(cf1->ClassValueArray[index]);
728 }
729 }
730 else if (GET_BE_WORD(cf1->ClassFormat) == 2)
731 {
732 const OT_ClassDefFormat2 *cf2 = table;
733 int i, top;
735 for (i = 0; i < top; i++)
736 {
737 if (glyph >= GET_BE_WORD(cf2->ClassRangeRecord[i].Start) &&
738 glyph <= GET_BE_WORD(cf2->ClassRangeRecord[i].End))
739 {
740 class = GET_BE_WORD(cf2->ClassRangeRecord[i].Class);
741 break;
742 }
743 }
744 }
745 else
746 ERR("Unknown Class Format %i\n",GET_BE_WORD(cf1->ClassFormat));
747
748 return class;
749}
GLdouble GLdouble GLdouble GLdouble top
Definition: glext.h:10859
OT_ClassRangeRecord ClassRangeRecord[1]
Definition: opentype.c:131

Referenced by GPOS_apply_ContextPos(), GPOS_apply_MarkToBase(), GPOS_apply_PairAdjustment(), GSUB_apply_ChainContextSubst(), GSUB_apply_ContextSubst(), and OpenType_GDEF_UpdateGlyphProps().

◆ usp10_language_add_feature_list()

static void usp10_language_add_feature_list ( LoadedLanguage language,
char  table_type,
const OT_LangSys lang,
const OT_FeatureList feature_list 
)
static

Definition at line 2813 of file opentype.c.

2815{
2816 unsigned int count = GET_BE_WORD(lang->FeatureCount);
2817 unsigned int i, j;
2818
2819 TRACE("table_type %#x, %u features.\n", table_type, count);
2820
2821 if (!count || !usp10_array_reserve((void **)&language->features, &language->features_size,
2822 language->feature_count + count, sizeof(*language->features)))
2823 return;
2824
2825 for (i = 0; i < count; ++i)
2826 {
2827 const OT_FeatureRecord *record;
2828 LoadedFeature *loaded_feature;
2829 const OT_Feature *feature;
2830
2831 record = &feature_list->FeatureRecord[GET_BE_WORD(lang->FeatureIndex[i])];
2832 feature = (const OT_Feature *)((const BYTE *)feature_list + GET_BE_WORD(record->Feature));
2833
2834 loaded_feature = &language->features[language->feature_count + i];
2835 loaded_feature->tag = MS_MAKE_TAG(record->FeatureTag[0], record->FeatureTag[1],
2836 record->FeatureTag[2], record->FeatureTag[3]);
2837 loaded_feature->tableType = table_type;
2838 loaded_feature->feature = feature;
2839 loaded_feature->lookup_count = GET_BE_WORD(feature->LookupCount);
2840 loaded_feature->lookups = heap_calloc(loaded_feature->lookup_count, sizeof(*loaded_feature->lookups));
2841 for (j = 0; j < loaded_feature->lookup_count; ++j)
2842 loaded_feature->lookups[j] = GET_BE_WORD(feature->LookupListIndex[j]);
2843 }
2844 language->feature_count += count;
2845}
#define MS_MAKE_TAG(ch0, ch1, ch2, ch3)
Definition: font.c:113
BOOL usp10_array_reserve(void **elements, SIZE_T *capacity, SIZE_T count, SIZE_T size)
Definition: usp10.c:730
static void * heap_calloc(SIZE_T count, SIZE_T size)
Definition: heap.h:49
const void * feature
OT_FeatureRecord FeatureRecord[1]
Definition: opentype.c:178

Referenced by _initialize_feature_cache().

◆ usp10_script_add_language()

static LoadedLanguage * usp10_script_add_language ( LoadedScript script,
OPENTYPE_TAG  tag 
)
static

Definition at line 2678 of file opentype.c.

2679{
2680 LoadedLanguage *language;
2681
2682 if (!usp10_array_reserve((void **)&script->languages, &script->languages_size,
2683 script->language_count + 1, sizeof(*script->languages)))
2684 {
2685 ERR("Failed to grow languages array.\n");
2686 return NULL;
2687 }
2688
2689 language = &script->languages[script->language_count++];
2690 language->tag = tag;
2691
2692 return language;
2693}
Definition: ecma_167.h:138

Referenced by usp10_script_add_language_list().

◆ usp10_script_add_language_list()

static void usp10_script_add_language_list ( LoadedScript script,
enum usp10_language_table  table,
const OT_Script list 
)
static

Definition at line 2708 of file opentype.c.

2710{
2711 SIZE_T initial_count, count, i;
2712 LoadedLanguage *language;
2714 DWORD offset;
2715
2716 TRACE("script %p, table %#x, list %p.\n", script, table, list);
2717
2718 if ((offset = GET_BE_WORD(list->DefaultLangSys)))
2719 {
2720 script->default_language.tag = MS_MAKE_TAG('d','f','l','t');
2721 script->default_language.table[table] = (const BYTE *)list + offset;
2722 TRACE("Default language %p.\n", script->default_language.table[table]);
2723 }
2724
2725 if (!(count = GET_BE_WORD(list->LangSysCount)))
2726 return;
2727
2728 TRACE("Adding %lu languages.\n", count);
2729
2730 initial_count = script->language_count;
2731 for (i = 0; i < count; ++i)
2732 {
2733 tag = MS_MAKE_TAG(list->LangSysRecord[i].LangSysTag[0],
2734 list->LangSysRecord[i].LangSysTag[1],
2735 list->LangSysRecord[i].LangSysTag[2],
2736 list->LangSysRecord[i].LangSysTag[3]);
2737
2738 if (!(initial_count && (language = usp10_script_get_language(script, tag)))
2739 && !(language = usp10_script_add_language(script, tag)))
2740 return;
2741
2742 language->table[table] = (const BYTE *)list + GET_BE_WORD(list->LangSysRecord[i].LangSys);
2743 }
2744}
static LoadedLanguage * usp10_script_add_language(LoadedScript *script, OPENTYPE_TAG tag)
Definition: opentype.c:2678
ULONG_PTR SIZE_T
Definition: typedefs.h:80
ULONG OPENTYPE_TAG
Definition: usp10.h:205

Referenced by _initialize_language_cache().

◆ usp10_script_cache_add_script()

static LoadedScript * usp10_script_cache_add_script ( ScriptCache script_cache,
OPENTYPE_TAG  tag 
)
static

Definition at line 2568 of file opentype.c.

2569{
2571
2572 if (!usp10_array_reserve((void **)&script_cache->scripts, &script_cache->scripts_size,
2573 script_cache->script_count + 1, sizeof(*script_cache->scripts)))
2574 {
2575 ERR("Failed to grow scripts array.\n");
2576 return NULL;
2577 }
2578
2579 script = &script_cache->scripts[script_cache->script_count++];
2580 script->tag = tag;
2581
2582 return script;
2583}
OPENTYPE_TAG tag
SIZE_T script_count
LoadedScript * scripts
SIZE_T scripts_size

Referenced by usp10_script_cache_add_script_list().

◆ usp10_script_cache_add_script_list()

static void usp10_script_cache_add_script_list ( ScriptCache script_cache,
enum usp10_script_table  table,
const OT_ScriptList list 
)
static

Definition at line 2598 of file opentype.c.

2600{
2601 SIZE_T initial_count, count, i;
2604
2605 TRACE("script_cache %p, table %#x, list %p.\n", script_cache, table, list);
2606
2607 if (!(count = GET_BE_WORD(list->ScriptCount)))
2608 return;
2609
2610 TRACE("Adding %lu scripts.\n", count);
2611
2612 initial_count = script_cache->script_count;
2613 for (i = 0; i < count; ++i)
2614 {
2615 tag = MS_MAKE_TAG(list->ScriptRecord[i].ScriptTag[0],
2616 list->ScriptRecord[i].ScriptTag[1],
2617 list->ScriptRecord[i].ScriptTag[2],
2618 list->ScriptRecord[i].ScriptTag[3]);
2619
2620 if (!(initial_count && (script = usp10_script_cache_get_script(script_cache, tag)))
2621 && !(script = usp10_script_cache_add_script(script_cache, tag)))
2622 return;
2623
2624 script->table[table] = (const BYTE *)list + GET_BE_WORD(list->ScriptRecord[i].Script);
2625 }
2626}
static LoadedScript * usp10_script_cache_add_script(ScriptCache *script_cache, OPENTYPE_TAG tag)
Definition: opentype.c:2568

Referenced by _initialize_script_cache().

◆ usp10_script_cache_get_script()

static LoadedScript * usp10_script_cache_get_script ( ScriptCache script_cache,
OPENTYPE_TAG  tag 
)
static

Definition at line 2585 of file opentype.c.

2586{
2587 size_t i;
2588
2589 for (i = 0; i < script_cache->script_count; ++i)
2590 {
2591 if (script_cache->scripts[i].tag == tag)
2592 return &script_cache->scripts[i];
2593 }
2594
2595 return NULL;
2596}

Referenced by OpenType_GetFontFeatureTags(), OpenType_GetFontLanguageTags(), OpenType_GetFontScriptTags(), and usp10_script_cache_add_script_list().

◆ usp10_script_get_language()

static LoadedLanguage * usp10_script_get_language ( LoadedScript script,
OPENTYPE_TAG  tag 
)
static

Definition at line 2695 of file opentype.c.

2696{
2697 size_t i;
2698
2699 for (i = 0; i < script->language_count; ++i)
2700 {
2701 if (script->languages[i].tag == tag)
2702 return &script->languages[i];
2703 }
2704
2705 return NULL;
2706}

Referenced by OpenType_GetFontFeatureTags(), and usp10_script_add_language_list().

◆ WINE_DEFAULT_DEBUG_CHANNEL()

WINE_DEFAULT_DEBUG_CHANNEL ( uniscribe  )