ReactOS 0.4.17-dev-1133-gc25e4fd
opentype.c File Reference
#include <stdarg.h>
#include <stdlib.h>
#include "windef.h"
#include "winbase.h"
#include "ntgdi.h"
#include "winuser.h"
#include "winnls.h"
#include "usp10.h"
#include "winternl.h"
#include "usp10_internal.h"
#include "wine/debug.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_SINGLE_ADJUSTMENT = 1 , GPOS_LOOKUP_PAIR_ADJUSTMENT = 2 , GPOS_LOOKUP_CURSIVE_ATTACHMENT = 3 , GPOS_LOOKUP_MARK_TO_BASE_ATTACHMENT = 4 ,
  GPOS_LOOKUP_MARK_TO_LIGATURE_ATTACHMENT = 5 , GPOS_LOOKUP_MARK_TO_MARK_ATTACHMENT = 6 , GPOS_LOOKUP_CONTEXTUAL_POSITION = 7 , GPOS_LOOKUP_CONTEXTUAL_CHAINING_POSITION = 8 ,
  GPOS_LOOKUP_EXTENSION_POSITION = 9 , 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_SUBST = 1 , GSUB_LOOKUP_MULTIPLE_SUBST = 2 , GSUB_LOOKUP_ALTERNATE_SUBST = 3 , GSUB_LOOKUP_LIGATURE_SUBST = 4 ,
  GSUB_LOOKUP_CONTEXTUAL_SUBST = 5 , GSUB_LOOKUP_CHAINING_CONTEXTUAL_SUBST = 6 , GSUB_LOOKUP_EXTENSION_SUBST = 7 , GSUB_LOOKUP_REVERSE_CHAINING_CONTEXTUAL_SUBST = 8 ,
  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 VOID * load_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 BYTE * GSUB_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 BYTE * GPOS_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 LoadedScript * usp10_script_cache_add_script (ScriptCache *script_cache, OPENTYPE_TAG tag)
 
static LoadedScript * usp10_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 LoadedLanguage * usp10_script_add_language (LoadedScript *script, OPENTYPE_TAG tag)
 
static LoadedLanguage * usp10_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 54 of file opentype.c.

◆ GET_BE_DWORD

#define GET_BE_DWORD (   x)    RtlUlongByteSwap(x)

Definition at line 48 of file opentype.c.

◆ GET_BE_WORD

#define GET_BE_WORD (   x)    RtlUshortByteSwap(x)

Definition at line 47 of file opentype.c.

◆ round

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

Definition at line 51 of file opentype.c.

Enumeration Type Documentation

◆ anonymous enum

anonymous enum
Enumerator
BaseGlyph 
LigatureGlyph 
MarkGlyph 
ComponentGlyph 

Definition at line 109 of file opentype.c.

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

◆ gpos_lookup_type

Enumerator
GPOS_LOOKUP_SINGLE_ADJUSTMENT 
GPOS_LOOKUP_PAIR_ADJUSTMENT 
GPOS_LOOKUP_CURSIVE_ATTACHMENT 
GPOS_LOOKUP_MARK_TO_BASE_ATTACHMENT 
GPOS_LOOKUP_MARK_TO_LIGATURE_ATTACHMENT 
GPOS_LOOKUP_MARK_TO_MARK_ATTACHMENT 
GPOS_LOOKUP_CONTEXTUAL_POSITION 
GPOS_LOOKUP_CONTEXTUAL_CHAINING_POSITION 
GPOS_LOOKUP_EXTENSION_POSITION 
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 56 of file opentype.c.

57{
67};
@ GPOS_LOOKUP_POSITION_CONTEXT_CHAINED
Definition: opentype.c:65
@ GPOS_LOOKUP_ATTACH_MARK_TO_LIGATURE
Definition: opentype.c:62
@ GPOS_LOOKUP_ADJUST_SINGLE
Definition: opentype.c:58
@ GPOS_LOOKUP_ADJUST_PAIR
Definition: opentype.c:59
@ GPOS_LOOKUP_ATTACH_MARK_TO_BASE
Definition: opentype.c:61
@ GPOS_LOOKUP_POSITION_EXTENSION
Definition: opentype.c:66
@ GPOS_LOOKUP_ATTACH_MARK_TO_MARK
Definition: opentype.c:63
@ GPOS_LOOKUP_ATTACH_CURSIVE
Definition: opentype.c:60
@ GPOS_LOOKUP_POSITION_CONTEXT
Definition: opentype.c:64

◆ gsub_lookup_type

Enumerator
GSUB_LOOKUP_SINGLE_SUBST 
GSUB_LOOKUP_MULTIPLE_SUBST 
GSUB_LOOKUP_ALTERNATE_SUBST 
GSUB_LOOKUP_LIGATURE_SUBST 
GSUB_LOOKUP_CONTEXTUAL_SUBST 
GSUB_LOOKUP_CHAINING_CONTEXTUAL_SUBST 
GSUB_LOOKUP_EXTENSION_SUBST 
GSUB_LOOKUP_REVERSE_CHAINING_CONTEXTUAL_SUBST 
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 69 of file opentype.c.

70{
79};
@ GSUB_LOOKUP_CONTEXT_CHAINED_REVERSE
Definition: opentype.c:78
@ GSUB_LOOKUP_LIGATURE
Definition: opentype.c:74
@ GSUB_LOOKUP_SINGLE
Definition: opentype.c:71
@ GSUB_LOOKUP_MULTIPLE
Definition: opentype.c:72
@ GSUB_LOOKUP_EXTENSION
Definition: opentype.c:77
@ GSUB_LOOKUP_CONTEXT_CHAINED
Definition: opentype.c:76
@ GSUB_LOOKUP_CONTEXT
Definition: opentype.c:75
@ GSUB_LOOKUP_ALTERNATE
Definition: opentype.c:73

Function Documentation

◆ _initialize_feature_cache()

static void _initialize_feature_cache ( ScriptCache *  psc,
LoadedLanguage *  language 
)
static

Definition at line 2889 of file opentype.c.

2890{
2891 const GSUB_Header *gsub_header = psc->GSUB_Table;
2892 const GPOS_Header *gpos_header = psc->GPOS_Table;
2893 const OT_FeatureList *feature_list;
2894 const OT_LangSys *lang;
2895
2896 if (language->features_initialized)
2897 return;
2898
2899 if ((lang = language->table[USP10_LANGUAGE_TABLE_GSUB]))
2900 {
2901 feature_list = (const OT_FeatureList *)((const BYTE *)gsub_header + GET_BE_WORD(gsub_header->FeatureList));
2903 }
2904
2905 if ((lang = language->table[USP10_LANGUAGE_TABLE_GPOS]))
2906 {
2907 feature_list = (const OT_FeatureList *)((const BYTE *)gpos_header + GET_BE_WORD(gpos_header->FeatureList));
2909 }
2910
2911 language->features_initialized = TRUE;
2912}
#define GET_BE_WORD(x)
Definition: opentype.c:67
#define TRUE
Definition: types.h:120
WORD FeatureList
Definition: opentype.c:401
WORD FeatureList
Definition: opentype.c:143
const void * table[USP10_LANGUAGE_TABLE_COUNT]
void * GPOS_Table
void * GSUB_Table
#define FEATURE_GSUB_TABLE
@ USP10_LANGUAGE_TABLE_GSUB
@ USP10_LANGUAGE_TABLE_GPOS
#define FEATURE_GPOS_TABLE
static const WCHAR lang[]
Definition: wbemdisp.c:287
static void usp10_language_add_feature_list(LoadedLanguage *language, char table_type, const OT_LangSys *lang, const OT_FeatureList *feature_list)
Definition: opentype.c:2855
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 2788 of file opentype.c.

2789{
2790 const OT_Script *list;
2791
2792 if (script->languages_initialized)
2793 return;
2794
2795 if ((list = script->table[USP10_SCRIPT_TABLE_GSUB]))
2797 if ((list = script->table[USP10_SCRIPT_TABLE_GPOS]))
2799
2800 script->languages_initialized = TRUE;
2801}
Definition: list.h:39
script
Definition: msipriv.h:396
#define list
Definition: rosglue.h:35
@ USP10_SCRIPT_TABLE_GSUB
@ USP10_SCRIPT_TABLE_GPOS
static void usp10_script_add_language_list(LoadedScript *script, enum usp10_language_table table, const OT_Script *list)
Definition: opentype.c:2750

Referenced by OpenType_GetFontFeatureTags(), and OpenType_GetFontLanguageTags().

◆ _initialize_script_cache()

static void _initialize_script_cache ( ScriptCache *  script_cache)
static

Definition at line 2670 of file opentype.c.

2671{
2672 const GPOS_Header *gpos_header;
2673 const GSUB_Header *gsub_header;
2674
2675 if (script_cache->scripts_initialized)
2676 return;
2677
2678 if ((gsub_header = script_cache->GSUB_Table))
2680 (const OT_ScriptList *)((const BYTE *)gsub_header + GET_BE_WORD(gsub_header->ScriptList)));
2681
2682 if ((gpos_header = script_cache->GPOS_Table))
2684 (const OT_ScriptList *)((const BYTE *)gpos_header + GET_BE_WORD(gpos_header->ScriptList)));
2685
2686 script_cache->scripts_initialized = TRUE;
2687}
WORD ScriptList
Definition: opentype.c:400
WORD ScriptList
Definition: opentype.c:142
BOOL scripts_initialized
static void usp10_script_cache_add_script_list(ScriptCache *script_cache, enum usp10_script_table table, const OT_ScriptList *list)
Definition: opentype.c:2640

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 1750 of file opentype.c.

1752{
1753 GPOS_ValueRecord val_rec1 = {0,0,0,0,0,0,0,0};
1754 GPOS_ValueRecord val_rec2 = {0,0,0,0,0,0,0,0};
1755 INT size;
1756
1757 size = GPOS_get_value_record( val_fmt1, pair, &val_rec1 );
1758 GPOS_get_value_record( val_fmt2, pair + size, &val_rec2 );
1759
1760 if (val_fmt1)
1761 {
1762 GPOS_get_value_record_offsets( pos_table, &val_rec1, val_fmt1, ppem, adjust, advance );
1763 TRACE( "Glyph 1 resulting cumulative offset is %s design units\n", wine_dbgstr_point(&adjust[0]) );
1764 TRACE( "Glyph 1 resulting cumulative advance is %s design units\n", wine_dbgstr_point(&advance[0]) );
1765 }
1766 if (val_fmt2)
1767 {
1768 GPOS_get_value_record_offsets( pos_table, &val_rec2, val_fmt2, ppem, adjust + 1, advance + 1 );
1769 TRACE( "Glyph 2 resulting cumulative offset is %s design units\n", wine_dbgstr_point(&adjust[1]) );
1770 TRACE( "Glyph 2 resulting cumulative advance is %s design units\n", wine_dbgstr_point(&advance[1]) );
1771 }
1772}
_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
#define TRACE(s)
Definition: solgame.cpp:4
Definition: _pair.h:47
int32_t INT
Definition: typedefs.h:58
static INT GPOS_get_value_record(WORD ValueFormat, const WORD data[], GPOS_ValueRecord *record)
Definition: opentype.c:1652
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:1666

Referenced by GPOS_apply_PairAdjustment().

◆ compare_group()

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

Definition at line 665 of file opentype.c.

666{
667 const DWORD *chr = a;
669
670 if (*chr < GET_BE_DWORD(group->startCharCode))
671 return -1;
672 if (*chr > GET_BE_DWORD(group->endCharCode))
673 return 1;
674 return 0;
675}
#define GET_BE_DWORD(x)
Definition: opentype.c:68
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

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 2275 of file opentype.c.

2279{
2280 int j;
2281 int write_dir = (analysis->fRTL && !analysis->fLogicalOrder) ? -1 : 1;
2282
2283 TRACE("Chaining Contextual Positioning Subtable\n");
2284
2285 for (j = 0; j < GET_BE_WORD(look->SubTableCount); j++)
2286 {
2287 int offset;
2289 int dirLookahead = write_dir;
2290 int dirBacktrack = -1 * write_dir;
2291
2292 if (GET_BE_WORD(backtrack->PosFormat) == 1)
2293 {
2294 static int once;
2295 if (!once++)
2296 FIXME(" TODO: subtype 1 (Simple Chaining Context Glyph Positioning)\n");
2297 continue;
2298 }
2299 else if (GET_BE_WORD(backtrack->PosFormat) == 2)
2300 {
2301 static int once;
2302 if (!once++)
2303 FIXME(" TODO: subtype 2 (Class-based Chaining Context Glyph Positioning)\n");
2304 continue;
2305 }
2306 else if (GET_BE_WORD(backtrack->PosFormat) == 3)
2307 {
2308 WORD backtrack_count, input_count, lookahead_count, positioning_count;
2309 int k;
2311 const GPOS_ChainContextPosFormat3_3 *lookahead;
2312 const GPOS_ChainContextPosFormat3_4 *positioning;
2313
2314 TRACE(" subtype 3 (Coverage-based Chaining Context Glyph Positioning)\n");
2315
2316 backtrack_count = GET_BE_WORD(backtrack->BacktrackGlyphCount);
2317 k = glyph_index + dirBacktrack * backtrack_count;
2318 if (k < 0 || k >= glyph_count)
2319 continue;
2320
2321 input = (const GPOS_ChainContextPosFormat3_2 *)&backtrack->Coverage[backtrack_count];
2322 input_count = GET_BE_WORD(input->InputGlyphCount);
2323 k = glyph_index + write_dir * (input_count - 1);
2324 if (k < 0 || k >= glyph_count)
2325 continue;
2326
2327 lookahead = (const GPOS_ChainContextPosFormat3_3 *)&input->Coverage[input_count];
2328 lookahead_count = GET_BE_WORD(lookahead->LookaheadGlyphCount);
2329 k = glyph_index + dirLookahead * (input_count + lookahead_count - 1);
2330 if (k < 0 || k >= glyph_count)
2331 continue;
2332
2333 positioning = (const GPOS_ChainContextPosFormat3_4 *)&lookahead->Coverage[lookahead_count];
2334
2335 for (k = 0; k < backtrack_count; ++k)
2336 {
2337 unsigned int prev_glyph_index;
2338 offset = GET_BE_WORD(backtrack->Coverage[k]);
2339 prev_glyph_index = glyph_index + (dirBacktrack * (k + 1));
2340 if (prev_glyph_index >= glyph_count)
2341 continue;
2342 if (GSUB_is_glyph_covered((const BYTE *)backtrack + offset, glyphs[prev_glyph_index]) == -1)
2343 break;
2344 }
2345 if (k != backtrack_count)
2346 continue;
2347 TRACE("Matched Backtrack\n");
2348
2349 for (k = 0; k < input_count; ++k)
2350 {
2351 unsigned int next_glyph_index = glyph_index + (write_dir * k);
2352 if (next_glyph_index >= glyph_count)
2353 continue;
2354 offset = GET_BE_WORD(input->Coverage[k]);
2355 if (GSUB_is_glyph_covered((const BYTE *)backtrack + offset,
2356 glyphs[next_glyph_index]) == -1)
2357 break;
2358 }
2359 if (k != input_count)
2360 continue;
2361 TRACE("Matched IndexGlyphs\n");
2362
2363 for (k = 0; k < lookahead_count; ++k)
2364 {
2365 unsigned int next_glyph_index = glyph_index + (dirLookahead * (input_count + k));
2366 if (next_glyph_index >= glyph_count)
2367 continue;
2368 offset = GET_BE_WORD(lookahead->Coverage[k]);
2369 if (GSUB_is_glyph_covered((const BYTE *)backtrack + offset,
2370 glyphs[next_glyph_index]) == -1)
2371 break;
2372 }
2373 if (k != lookahead_count)
2374 continue;
2375 TRACE("Matched LookAhead\n");
2376
2377 if (!(positioning_count = GET_BE_WORD(positioning->PosCount)))
2378 return 1;
2379
2380 for (k = 0; k < positioning_count; ++k)
2381 {
2382 unsigned int lookup_index = GET_BE_WORD(positioning->PosLookupRecord[k].LookupListIndex);
2383 unsigned int sequence_index = GET_BE_WORD(positioning->PosLookupRecord[k].SequenceIndex);
2384 unsigned int g = glyph_index + write_dir * sequence_index;
2385
2386 if (g >= glyph_count)
2387 {
2388 WARN("Skipping invalid sequence index %u (glyph index %u, write dir %d).\n",
2389 sequence_index, glyph_index, write_dir);
2390 continue;
2391 }
2392
2393 TRACE("Position: %u -> %u %u.\n", k, sequence_index, lookup_index);
2394 GPOS_apply_lookup(script_cache, otm, logfont, analysis, advance, lookup, lookup_index,
2395 glyphs, g, glyph_count, goffset);
2396 }
2397 return input_count + lookahead_count;
2398 }
2399 else
2400 FIXME("Unhandled Chaining Contextual Positioning Format %#x.\n", GET_BE_WORD(backtrack->PosFormat));
2401 }
2402 return 1;
2403}
#define FIXME(fmt,...)
Definition: precomp.h:53
#define WARN(fmt,...)
Definition: precomp.h:61
static const uint32_t k[]
Definition: sha256.c:24
unsigned short WORD
Definition: ntddk_ex.h:93
GLintptr offset
Definition: glext.h:5920
GLboolean GLboolean g
Definition: glext.h:6204
GLenum GLenum GLenum input
Definition: glext.h:9031
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
for(i=0;i< sizeof(testsuite)/sizeof(testsuite[0]);++i) ok(call_test(testsuite[i].func)
GPOS_PosLookupRecord PosLookupRecord[1]
Definition: opentype.c:618
WORD SubTableCount
Definition: opentype.c:199
WORD fLogicalOrder
Definition: usp10.h:144
static int GSUB_is_glyph_covered(const void *table, unsigned int glyph)
Definition: opentype.c:823
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:2405
static const BYTE * GPOS_get_subtable(const OT_LookupTable *look, int index)
Definition: opentype.c:1680

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 2152 of file opentype.c.

2156{
2157 int j;
2158 int write_dir = (analysis->fRTL && !analysis->fLogicalOrder) ? -1 : 1;
2159
2160 TRACE("Contextual Positioning Subtable\n");
2161
2162 for (j = 0; j < GET_BE_WORD(look->SubTableCount); j++)
2163 {
2165
2166 if (GET_BE_WORD(cpf2->PosFormat) == 1)
2167 {
2168 static int once;
2169 if (!once++)
2170 FIXME(" TODO: subtype 1\n");
2171 continue;
2172 }
2173 else if (GET_BE_WORD(cpf2->PosFormat) == 2)
2174 {
2176 int index;
2177
2178 TRACE("Contextual Positioning Subtable: Format 2\n");
2179
2180 index = GSUB_is_glyph_covered((const BYTE*)cpf2+offset, glyphs[glyph_index]);
2181 TRACE("Coverage index %i\n",index);
2182 if (index != -1)
2183 {
2184 int k, count, class;
2185 const GPOS_PosClassSet *pcs;
2186 const void *glyph_class_table = NULL;
2187
2188 offset = GET_BE_WORD(cpf2->ClassDef);
2189 glyph_class_table = (const BYTE *)cpf2 + offset;
2190
2191 class = OT_get_glyph_class(glyph_class_table,glyphs[glyph_index]);
2192
2193 offset = GET_BE_WORD(cpf2->PosClassSet[class]);
2194 if (offset == 0)
2195 {
2196 TRACE("No class rule table for class %i\n",class);
2197 continue;
2198 }
2199 pcs = (const GPOS_PosClassSet*)((const BYTE*)cpf2+offset);
2201 TRACE("PosClassSet has %i members\n",count);
2202 for (k = 0; k < count; k++)
2203 {
2204 const GPOS_PosClassRule_1 *pr;
2205 const GPOS_PosClassRule_2 *pr_2;
2206 unsigned int g;
2207 int g_count, l;
2208
2210 pr = (const GPOS_PosClassRule_1*)((const BYTE*)pcs+offset);
2211 g_count = GET_BE_WORD(pr->GlyphCount);
2212 TRACE("PosClassRule has %i glyphs classes\n",g_count);
2213
2214 g = glyph_index + write_dir * (g_count - 1);
2215 if (g >= glyph_count)
2216 continue;
2217
2218 for (l = 0; l < g_count-1; l++)
2219 {
2220 g = glyph_index + (write_dir * (l+1));
2221 if (g < glyph_count)
2222 {
2223 int g_class = OT_get_glyph_class(glyph_class_table, glyphs[g]);
2224 if (g_class != GET_BE_WORD(pr->Class[l])) break;
2225 }
2226 }
2227
2228 if (l < g_count-1)
2229 {
2230 TRACE("Rule does not match\n");
2231 continue;
2232 }
2233
2234 TRACE("Rule matches\n");
2235 pr_2 = (const GPOS_PosClassRule_2 *)&pr->Class[g_count - 1];
2236
2237 for (l = 0; l < GET_BE_WORD(pr->PosCount); l++)
2238 {
2239 unsigned int lookup_index = GET_BE_WORD(pr_2->PosLookupRecord[l].LookupListIndex);
2240 unsigned int sequence_index = GET_BE_WORD(pr_2->PosLookupRecord[l].SequenceIndex);
2241
2242 g = glyph_index + write_dir * sequence_index;
2243 if (g >= glyph_count)
2244 {
2245 WARN("Invalid sequence index %u (glyph index %u, write dir %d).\n",
2246 sequence_index, glyph_index, write_dir);
2247 continue;
2248 }
2249
2250 TRACE("Position: %u -> %u %u.\n", l, sequence_index, lookup_index);
2251
2252 GPOS_apply_lookup(script_cache, otm, logfont, analysis, advance,
2253 lookup, lookup_index, glyphs, g, glyph_count, goffset);
2254 }
2255 return 1;
2256 }
2257 }
2258
2259 TRACE("Not covered\n");
2260 continue;
2261 }
2262 else if (GET_BE_WORD(cpf2->PosFormat) == 3)
2263 {
2264 static int once;
2265 if (!once++)
2266 FIXME(" TODO: subtype 3\n");
2267 continue;
2268 }
2269 else
2270 FIXME("Unhandled Contextual Positioning Format %i\n",GET_BE_WORD(cpf2->PosFormat));
2271 }
2272 return 1;
2273}
#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
GPOS_PosLookupRecord PosLookupRecord[1]
Definition: opentype.c:597
WORD PosClassRuleCnt
Definition: opentype.c:586
WORD PosClassRule[1]
Definition: opentype.c:587
static WORD OT_get_glyph_class(const void *table, WORD glyph)
Definition: opentype.c:718

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 1862 of file opentype.c.

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

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 2405 of file opentype.c.

2409{
2410 int offset;
2411 const OT_LookupTable *look;
2412 int ppem = lpotm->otmTextMetrics.tmAscent + lpotm->otmTextMetrics.tmDescent - lpotm->otmTextMetrics.tmInternalLeading;
2414
2415 offset = GET_BE_WORD(lookup->Lookup[lookup_index]);
2416 look = (const OT_LookupTable*)((const BYTE*)lookup + offset);
2417 type = GET_BE_WORD(look->LookupType);
2418 TRACE("type %#x, flag %#x, subtables %u.\n", type,
2420
2422 {
2423 if (GET_BE_WORD(look->SubTableCount))
2424 {
2425 const GPOS_ExtensionPosFormat1 *ext = (const GPOS_ExtensionPosFormat1 *)((const BYTE *)look + GET_BE_WORD(look->SubTable[0]));
2426 if (GET_BE_WORD(ext->PosFormat) == 1)
2427 {
2428 type = GET_BE_WORD(ext->ExtensionLookupType);
2429 TRACE("extension type %i\n",type);
2430 }
2431 else
2432 {
2433 FIXME("Unhandled Extension Positioning Format %i\n",GET_BE_WORD(ext->PosFormat));
2434 }
2435 }
2436 else
2437 {
2438 WARN("lookup type is Extension Positioning but no extension subtable exists\n");
2439 }
2440 }
2441 switch (type)
2442 {
2444 {
2445 double devX, devY;
2446 POINT adjust = {0,0};
2447 POINT advance = {0,0};
2448 GPOS_apply_SingleAdjustment(look, analysis, glyphs, glyph_index, glyph_count, ppem, &adjust, &advance);
2449 if (adjust.x || adjust.y)
2450 {
2451 GPOS_convert_design_units_to_device(lpotm, lplogfont, adjust.x, adjust.y, &devX, &devY);
2452 pGoffset[glyph_index].du += round(devX);
2453 pGoffset[glyph_index].dv += round(devY);
2454 }
2455 if (advance.x || advance.y)
2456 {
2457 GPOS_convert_design_units_to_device(lpotm, lplogfont, advance.x, advance.y, &devX, &devY);
2458 piAdvance[glyph_index] += round(devX);
2459 if (advance.y)
2460 FIXME("Unhandled adjustment to Y advancement\n");
2461 }
2462 break;
2463 }
2464
2466 {
2467 POINT advance[2]= {{0,0},{0,0}};
2468 POINT adjust[2]= {{0,0},{0,0}};
2469 double devX, devY;
2470 int index_offset;
2471 int write_dir = (analysis->fRTL && !analysis->fLogicalOrder) ? -1 : 1;
2472 int offset_sign = (analysis->fRTL && analysis->fLogicalOrder) ? -1 : 1;
2473 unsigned int next_glyph_index = glyph_index + write_dir;
2474 if (next_glyph_index >= glyph_count)
2475 {
2476 WARN("Skipping invalid glyph index %u, write dir %d.\n", glyph_index, write_dir);
2477 break;
2478 }
2479
2480 index_offset = GPOS_apply_PairAdjustment(look, analysis, glyphs,
2481 glyph_index, glyph_count, ppem, adjust, advance);
2482 if (adjust[0].x || adjust[0].y)
2483 {
2484 GPOS_convert_design_units_to_device(lpotm, lplogfont, adjust[0].x, adjust[0].y, &devX, &devY);
2485 pGoffset[glyph_index].du += round(devX) * offset_sign;
2486 pGoffset[glyph_index].dv += round(devY);
2487 }
2488 if (advance[0].x || advance[0].y)
2489 {
2490 GPOS_convert_design_units_to_device(lpotm, lplogfont, advance[0].x, advance[0].y, &devX, &devY);
2491 piAdvance[glyph_index] += round(devX);
2492 }
2493 if (adjust[1].x || adjust[1].y)
2494 {
2495 GPOS_convert_design_units_to_device(lpotm, lplogfont, adjust[1].x, adjust[1].y, &devX, &devY);
2496 pGoffset[next_glyph_index].du += round(devX) * offset_sign;
2497 pGoffset[next_glyph_index].dv += round(devY);
2498 }
2499 if (advance[1].x || advance[1].y)
2500 {
2501 GPOS_convert_design_units_to_device(lpotm, lplogfont, advance[1].x, advance[1].y, &devX, &devY);
2502 piAdvance[next_glyph_index] += round(devX);
2503 }
2504 return index_offset;
2505 }
2506
2508 {
2509 POINT desU = {0,0};
2510 double devX, devY;
2511 int write_dir = (analysis->fRTL && !analysis->fLogicalOrder) ? -1 : 1;
2512 unsigned int next_glyph_index = glyph_index + write_dir;
2513 if (next_glyph_index >= glyph_count)
2514 {
2515 WARN("Skipping invalid glyph index %u, write dir %d.\n", glyph_index, write_dir);
2516 break;
2517 }
2518
2519 GPOS_apply_CursiveAttachment(look, analysis, glyphs, glyph_index, glyph_count, ppem, &desU);
2520 if (desU.x || desU.y)
2521 {
2522 GPOS_convert_design_units_to_device(lpotm, lplogfont, desU.x, desU.y, &devX, &devY);
2523 /* Windows does not appear to apply X offsets here */
2524 pGoffset[glyph_index].dv = round(devY) + pGoffset[next_glyph_index].dv;
2525 }
2526 break;
2527 }
2528
2530 {
2531 double devX, devY;
2532 POINT desU = {0,0};
2533 int base_index = GPOS_apply_MarkToBase(script_cache, look, analysis,
2534 glyphs, glyph_index, glyph_count, ppem, &desU);
2535 if (base_index != -1)
2536 {
2537 GPOS_convert_design_units_to_device(lpotm, lplogfont, desU.x, desU.y, &devX, &devY);
2538 if (!analysis->fRTL) pGoffset[glyph_index].du = round(devX) - piAdvance[base_index];
2539 else
2540 {
2541 if (analysis->fLogicalOrder) devX *= -1;
2542 pGoffset[glyph_index].du = round(devX);
2543 }
2544 pGoffset[glyph_index].dv = round(devY);
2545 }
2546 break;
2547 }
2548
2550 {
2551 double devX, devY;
2552 POINT desU = {0,0};
2553 GPOS_apply_MarkToLigature(look, analysis, glyphs, glyph_index, glyph_count, ppem, &desU);
2554 if (desU.x || desU.y)
2555 {
2556 GPOS_convert_design_units_to_device(lpotm, lplogfont, desU.x, desU.y, &devX, &devY);
2557 pGoffset[glyph_index].du = (round(devX) - piAdvance[glyph_index-1]);
2558 pGoffset[glyph_index].dv = round(devY);
2559 }
2560 break;
2561 }
2562
2564 {
2565 double devX, devY;
2566 POINT desU = {0,0};
2567 int write_dir = (analysis->fRTL && !analysis->fLogicalOrder) ? -1 : 1;
2568 unsigned int prev_glyph_index = glyph_index - write_dir;
2569 if (prev_glyph_index >= glyph_count)
2570 {
2571 WARN("Skipping invalid glyph index %u, write dir %d.\n", glyph_index, write_dir);
2572 break;
2573 }
2574
2575 if (GPOS_apply_MarkToMark(look, analysis, glyphs, glyph_index, glyph_count, ppem, &desU))
2576 {
2577 GPOS_convert_design_units_to_device(lpotm, lplogfont, desU.x, desU.y, &devX, &devY);
2578 if (analysis->fRTL && analysis->fLogicalOrder) devX *= -1;
2579 pGoffset[glyph_index].du = round(devX) + pGoffset[prev_glyph_index].du;
2580 pGoffset[glyph_index].dv = round(devY) + pGoffset[prev_glyph_index].dv;
2581 }
2582 break;
2583 }
2584
2586 return GPOS_apply_ContextPos(script_cache, lpotm, lplogfont, analysis, piAdvance,
2587 lookup, look, glyphs, glyph_index, glyph_count, pGoffset);
2588
2590 return GPOS_apply_ChainContextPos(script_cache, lpotm, lplogfont, analysis, piAdvance,
2591 lookup, look, glyphs, glyph_index, glyph_count, pGoffset);
2592
2593 default:
2594 FIXME("Unhandled GPOS lookup type %#x.\n", type);
2595 }
2596 return 1;
2597}
gpos_lookup_type
Definition: opentype.c:529
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
WORD SubTable[1]
Definition: opentype.c:200
WORD LookupFlag
Definition: opentype.c:198
WORD LookupType
Definition: opentype.c:197
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:1699
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:1774
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:2275
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:1862
#define round(x)
Definition: opentype.c:51
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:1904
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:1640
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:1989
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:2079
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:2152

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 1904 of file opentype.c.

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

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

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 2079 of file opentype.c.

2081{
2082 int j;
2083 BOOL rc = FALSE;
2084 int write_dir = (analysis->fRTL && !analysis->fLogicalOrder) ? -1 : 1;
2085
2086 TRACE("MarkToMark Attachment Positioning Subtable\n");
2087
2088 for (j = 0; j < GET_BE_WORD(look->SubTableCount); j++)
2089 {
2091 if (GET_BE_WORD(mmpf1->PosFormat) == 1)
2092 {
2093 int offset = GET_BE_WORD(mmpf1->Mark1Coverage);
2094 int mark_index;
2095 mark_index = GSUB_is_glyph_covered((const BYTE*)mmpf1+offset, glyphs[glyph_index]);
2096 if (mark_index != -1)
2097 {
2098 int mark2_index;
2099 unsigned int prev_glyph_index = glyph_index - write_dir;
2100 if (prev_glyph_index >= glyph_count)
2101 {
2102 TRACE("Mark looking outside range\n");
2103 return FALSE;
2104 }
2106 mark2_index = GSUB_is_glyph_covered((const BYTE*)mmpf1+offset, glyphs[prev_glyph_index]);
2107 if (mark2_index != -1)
2108 {
2109 const GPOS_MarkArray *ma;
2110 const GPOS_MarkRecord *mr;
2111 const GPOS_Mark2Array *m2a;
2112 const GPOS_Mark2Record *m2r;
2113 int mark_class;
2114 int class_count = GET_BE_WORD(mmpf1->ClassCount);
2115 int mark2record_size;
2116 POINT mark2_pt;
2117 POINT mark_pt;
2118 TRACE("Mark %x(%i) and Mark2 %x(%i)\n",glyphs[glyph_index], mark_index, glyphs[prev_glyph_index], mark2_index);
2119 offset = GET_BE_WORD(mmpf1->Mark1Array);
2120 ma = (const GPOS_MarkArray*)((const BYTE*)mmpf1 + offset);
2121 if (mark_index > GET_BE_WORD(ma->MarkCount))
2122 {
2123 ERR("Mark index exceeded mark count\n");
2124 return FALSE;
2125 }
2126 mr = &ma->MarkRecord[mark_index];
2127 mark_class = GET_BE_WORD(mr->Class);
2128 TRACE("Mark Class %i total classes %i\n",mark_class,class_count);
2129 offset = GET_BE_WORD(mmpf1->Mark2Array);
2130 m2a = (const GPOS_Mark2Array*)((const BYTE*)mmpf1 + offset);
2131 mark2record_size = class_count * sizeof(WORD);
2132 m2r = (const GPOS_Mark2Record*)((const BYTE*)m2a + sizeof(WORD) + (mark2record_size * mark2_index));
2133 offset = GET_BE_WORD(m2r->Mark2Anchor[mark_class]);
2134 GPOS_get_anchor_values((const BYTE*)m2a + offset, &mark2_pt, ppem);
2136 GPOS_get_anchor_values((const BYTE*)ma + offset, &mark_pt, ppem);
2137 TRACE("Offset on mark2 is %s design units\n",wine_dbgstr_point(&mark2_pt));
2138 TRACE("Offset on mark is %s design units\n",wine_dbgstr_point(&mark_pt));
2139 pt->x += mark2_pt.x - mark_pt.x;
2140 pt->y += mark2_pt.y - mark_pt.y;
2141 TRACE("Resulting cumulative offset is %s design units\n",wine_dbgstr_point(pt));
2142 rc = TRUE;
2143 }
2144 }
2145 }
2146 else
2147 FIXME("Unhandled Mark To Mark Format %i\n",GET_BE_WORD(mmpf1->PosFormat));
2148 }
2149 return rc;
2150}
#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 1774 of file opentype.c.

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

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 1699 of file opentype.c.

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

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 1640 of file opentype.c.

1642{
1644
1645 TRACE("emHeight %i lfWidth %li\n",emHeight, logfont->lfWidth);
1646 *devX = (desX * emHeight) / (double)otm->otmEMSquare;
1647 *devY = (desY * emHeight) / (double)otm->otmEMSquare;
1648 if (logfont->lfWidth)
1649 FIXME("Font with lfWidth set not handled properly.\n");
1650}
LONG lfWidth
Definition: dimm.idl:60
TEXTMETRICW otmTextMetrics
Definition: wingdi.h:2960
LONG tmAscent
Definition: wingdi.h:2830
LONG tmInternalLeading
Definition: wingdi.h:2832
LONG tmDescent
Definition: wingdi.h:2831

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 1588 of file opentype.c.

1589{
1590 const GPOS_AnchorFormat1* anchor1 = (const GPOS_AnchorFormat1*)table;
1591
1592 switch (GET_BE_WORD(anchor1->AnchorFormat))
1593 {
1594 case 1:
1595 {
1596 TRACE("Anchor Format 1\n");
1597 pt->x = (short)GET_BE_WORD(anchor1->XCoordinate);
1598 pt->y = (short)GET_BE_WORD(anchor1->YCoordinate);
1599 break;
1600 }
1601 case 2:
1602 {
1603 const GPOS_AnchorFormat2* anchor2 = (const GPOS_AnchorFormat2*)table;
1604 TRACE("Anchor Format 2\n");
1605 pt->x = (short)GET_BE_WORD(anchor2->XCoordinate);
1606 pt->y = (short)GET_BE_WORD(anchor2->YCoordinate);
1607 break;
1608 }
1609 case 3:
1610 {
1611 int offset;
1612 const GPOS_AnchorFormat3* anchor3 = (const GPOS_AnchorFormat3*)table;
1613 TRACE("Anchor Format 3\n");
1614 pt->x = (short)GET_BE_WORD(anchor3->XCoordinate);
1615 pt->y = (short)GET_BE_WORD(anchor3->YCoordinate);
1616 offset = GET_BE_WORD(anchor3->XDeviceTable);
1617 TRACE("ppem %i\n",ppem);
1618 if (offset)
1619 {
1620 const OT_DeviceTable* DeviceTableX = NULL;
1621 DeviceTableX = (const OT_DeviceTable*)((const BYTE*)anchor3 + offset);
1622 pt->x += GPOS_get_device_table_value(DeviceTableX, ppem);
1623 }
1624 offset = GET_BE_WORD(anchor3->YDeviceTable);
1625 if (offset)
1626 {
1627 const OT_DeviceTable* DeviceTableY = NULL;
1628 DeviceTableY = (const OT_DeviceTable*)((const BYTE*)anchor3 + offset);
1629 pt->y += GPOS_get_device_table_value(DeviceTableY, ppem);
1630 }
1631 break;
1632 }
1633 default:
1634 ERR("Unknown Anchor Format %i\n",GET_BE_WORD(anchor1->AnchorFormat));
1635 pt->x = 0;
1636 pt->y = 0;
1637 }
1638}
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:1561

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 1561 of file opentype.c.

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

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 1680 of file opentype.c.

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

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 1652 of file opentype.c.

1653{
1654 INT offset = 0;
1655 if (ValueFormat & 0x0001) { if (data) record->XPlacement = GET_BE_WORD(data[offset]); offset++; }
1656 if (ValueFormat & 0x0002) { if (data) record->YPlacement = GET_BE_WORD(data[offset]); offset++; }
1657 if (ValueFormat & 0x0004) { if (data) record->XAdvance = GET_BE_WORD(data[offset]); offset++; }
1658 if (ValueFormat & 0x0008) { if (data) record->YAdvance = GET_BE_WORD(data[offset]); offset++; }
1659 if (ValueFormat & 0x0010) { if (data) record->XPlaDevice = GET_BE_WORD(data[offset]); offset++; }
1660 if (ValueFormat & 0x0020) { if (data) record->YPlaDevice = GET_BE_WORD(data[offset]); offset++; }
1661 if (ValueFormat & 0x0040) { if (data) record->XAdvDevice = GET_BE_WORD(data[offset]); offset++; }
1662 if (ValueFormat & 0x0080) { if (data) record->YAdvDevice = GET_BE_WORD(data[offset]); offset++; }
1663 return offset;
1664}
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 1666 of file opentype.c.

1668{
1669 if (ValueFormat & 0x0001) ptPlacement->x += (short)ValueRecord->XPlacement;
1670 if (ValueFormat & 0x0002) ptPlacement->y += (short)ValueRecord->YPlacement;
1671 if (ValueFormat & 0x0004) ptAdvance->x += (short)ValueRecord->XAdvance;
1672 if (ValueFormat & 0x0008) ptAdvance->y += (short)ValueRecord->YAdvance;
1673 if (ValueFormat & 0x0010) ptPlacement->x += GPOS_get_device_table_value((const OT_DeviceTable*)(head + ValueRecord->XPlaDevice), ppem);
1674 if (ValueFormat & 0x0020) ptPlacement->y += GPOS_get_device_table_value((const OT_DeviceTable*)(head + ValueRecord->YPlaDevice), ppem);
1675 if (ValueFormat & 0x0040) ptAdvance->x += GPOS_get_device_table_value((const OT_DeviceTable*)(head + ValueRecord->XAdvDevice), ppem);
1676 if (ValueFormat & 0x0080) ptAdvance->y += GPOS_get_device_table_value((const OT_DeviceTable*)(head + ValueRecord->YAdvDevice), ppem);
1677 if (ValueFormat & 0xFF00) FIXME("Unhandled Value Format %x\n",ValueFormat&0xFF00);
1678}
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 982 of file opentype.c.

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

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 1249 of file opentype.c.

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

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 1078 of file opentype.c.

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

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 1015 of file opentype.c.

1016{
1017 int j;
1018
1019 TRACE("Ligature Substitution Subtable\n");
1020 for (j = 0; j < GET_BE_WORD(look->SubTableCount); j++)
1021 {
1022 const GSUB_LigatureSubstFormat1 *lsf1;
1023 int offset,index;
1024
1025 lsf1 = (const GSUB_LigatureSubstFormat1*)GSUB_get_subtable(look, j);
1026 offset = GET_BE_WORD(lsf1->Coverage);
1027 index = GSUB_is_glyph_covered((const BYTE*)lsf1+offset, glyphs[glyph_index]);
1028 TRACE(" Coverage index %i\n",index);
1029 if (index != -1)
1030 {
1031 const GSUB_LigatureSet *ls;
1032 int k, count;
1033
1035 ls = (const GSUB_LigatureSet*)((const BYTE*)lsf1+offset);
1036 count = GET_BE_WORD(ls->LigatureCount);
1037 TRACE(" LigatureSet has %i members\n",count);
1038 for (k = 0; k < count; k++)
1039 {
1040 const GSUB_Ligature *lig;
1041 int CompCount,l,CompIndex;
1042
1043 offset = GET_BE_WORD(ls->Ligature[k]);
1044 lig = (const GSUB_Ligature*)((const BYTE*)ls+offset);
1045 CompCount = GET_BE_WORD(lig->CompCount) - 1;
1046 CompIndex = glyph_index+write_dir;
1047 for (l = 0; l < CompCount && CompIndex >= 0 && CompIndex < *glyph_count; l++)
1048 {
1049 int CompGlyph;
1050 CompGlyph = GET_BE_WORD(lig->Component[l]);
1051 if (CompGlyph != glyphs[CompIndex])
1052 break;
1053 CompIndex += write_dir;
1054 }
1055 if (l == CompCount)
1056 {
1057 int replaceIdx = glyph_index;
1058 if (write_dir < 0)
1059 replaceIdx = glyph_index - CompCount;
1060
1061 TRACE(" Glyph is 0x%x (+%i) ->",glyphs[glyph_index],CompCount);
1062 glyphs[replaceIdx] = GET_BE_WORD(lig->LigGlyph);
1063 TRACE("0x%x\n",glyphs[replaceIdx]);
1064 if (CompCount > 0)
1065 {
1066 unsigned int j = replaceIdx + 1;
1067 memmove(&glyphs[j], &glyphs[j + CompCount], (*glyph_count - j) * sizeof(*glyphs));
1068 *glyph_count = *glyph_count - CompCount;
1069 }
1070 return replaceIdx + write_dir;
1071 }
1072 }
1073 }
1074 }
1075 return GSUB_E_NOGLYPH;
1076}
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:261
WORD CompCount
Definition: opentype.c:260
WORD LigGlyph
Definition: opentype.c:259

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 1489 of file opentype.c.

1490{
1491 int offset;
1493 const OT_LookupTable *look;
1494
1495 offset = GET_BE_WORD(lookup->Lookup[lookup_index]);
1496 look = (const OT_LookupTable*)((const BYTE*)lookup + offset);
1497 type = GET_BE_WORD(look->LookupType);
1498 TRACE("type %#x, flag %#x, subtables %u.\n", type,
1500
1502 {
1503 if (GET_BE_WORD(look->SubTableCount))
1504 {
1505 const GSUB_ExtensionPosFormat1 *ext = (const GSUB_ExtensionPosFormat1 *)((const BYTE *)look + GET_BE_WORD(look->SubTable[0]));
1506 if (GET_BE_WORD(ext->SubstFormat) == 1)
1507 {
1508 type = GET_BE_WORD(ext->ExtensionLookupType);
1509 TRACE("extension type %i\n",type);
1510 }
1511 else
1512 {
1513 FIXME("Unhandled Extension Substitution Format %i\n",GET_BE_WORD(ext->SubstFormat));
1514 }
1515 }
1516 else
1517 {
1518 WARN("lookup type is Extension Substitution but no extension subtable exists\n");
1519 }
1520 }
1521 switch(type)
1522 {
1523 case GSUB_LOOKUP_SINGLE:
1524 return GSUB_apply_SingleSubst(look, glyphs, glyph_index, write_dir, glyph_count);
1526 return GSUB_apply_MultipleSubst(look, glyphs, glyph_index, write_dir, glyph_count);
1528 return GSUB_apply_AlternateSubst(look, glyphs, glyph_index, write_dir, glyph_count);
1530 return GSUB_apply_LigatureSubst(look, glyphs, glyph_index, write_dir, glyph_count);
1532 return GSUB_apply_ContextSubst(lookup, look, glyphs, glyph_index, write_dir, glyph_count);
1534 return GSUB_apply_ChainContextSubst(lookup, look, glyphs, glyph_index, write_dir, glyph_count);
1536 FIXME("Extension Substitution types not valid here\n");
1537 break;
1538 default:
1539 FIXME("Unhandled GSUB lookup type %#x.\n", type);
1540 }
1541 return GSUB_E_NOGLYPH;
1542}
gsub_lookup_type
Definition: opentype.c:542
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:1078
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:1249
static INT GSUB_apply_LigatureSubst(const OT_LookupTable *look, WORD *glyphs, INT glyph_index, INT write_dir, INT *glyph_count)
Definition: opentype.c:1015
static INT GSUB_apply_SingleSubst(const OT_LookupTable *look, WORD *glyphs, INT glyph_index, INT write_dir, INT *glyph_count)
Definition: opentype.c:886
static INT GSUB_apply_MultipleSubst(const OT_LookupTable *look, WORD *glyphs, INT glyph_index, INT write_dir, INT *glyph_count)
Definition: opentype.c:932
static INT GSUB_apply_AlternateSubst(const OT_LookupTable *look, WORD *glyphs, INT glyph_index, INT write_dir, INT *glyph_count)
Definition: opentype.c:982

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 932 of file opentype.c.

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

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 886 of file opentype.c.

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

Referenced by GSUB_apply_lookup().

◆ GSUB_get_subtable()

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

Definition at line 867 of file opentype.c.

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

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 823 of file opentype.c.

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

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 631 of file opentype.c.

632{
633 CMAP_Header *CMAP_Table = NULL;
634 int length;
635 int i;
636
637 if (!psc->CMAP_Table)
638 {
640 if (length != GDI_ERROR)
641 {
642 psc->CMAP_Table = malloc(length);
644 TRACE("Loaded cmap table of %i bytes\n",length);
645 }
646 else
647 return NULL;
648 }
649
650 CMAP_Table = psc->CMAP_Table;
651
652 for (i = 0; i < GET_BE_WORD(CMAP_Table->numTables); i++)
653 {
654 if ( (GET_BE_WORD(CMAP_Table->tables[i].platformID) == 3) &&
655 (GET_BE_WORD(CMAP_Table->tables[i].encodingID) == 10) )
656 {
658 if (GET_BE_WORD(format->format) == 12)
659 return format;
660 }
661 }
662 return NULL;
663}
#define malloc
Definition: debug_ros.c:4
GLuint GLsizei GLsizei * length
Definition: glext.h:6040
HDC hdc
Definition: main.c:9
CMAP_EncodingRecord tables[1]
Definition: opentype.c:90
WORD numTables
Definition: opentype.c:89
void * CMAP_Table
#define CMAP_TAG
Definition: opentype.c:54
#define NtGdiGetFontData(A, B, C, D, E)
Definition: wine-compat.h:4
#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 2599 of file opentype.c.

2602{
2603 const GPOS_Header *header = (const GPOS_Header *)script_cache->GPOS_Table;
2604 const OT_LookupList *lookup = (const OT_LookupList*)((const BYTE*)header + GET_BE_WORD(header->LookupList));
2605
2606 return GPOS_apply_lookup(script_cache, otm, logfont, analysis, advance, lookup,
2607 lookup_index, glyphs, glyph_index, glyph_count, goffset);
2608}

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 1544 of file opentype.c.

1546{
1547 const GSUB_Header *header = (const GSUB_Header *)table;
1548 const OT_LookupList *lookup = (const OT_LookupList*)((const BYTE*)header + GET_BE_WORD(header->LookupList));
1549
1550 return GSUB_apply_lookup(lookup, lookup_index, glyphs, glyph_index, write_dir, glyph_count);
1551}

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 677 of file opentype.c.

678{
679 /* BMP: use gdi32 for ease */
680 if (utf32c < 0x10000)
681 {
682 WCHAR ch = utf32c;
683 return NtGdiGetGlyphIndicesW(hdc, &ch, 1, glyph_index, flags);
684 }
685
686 if (!psc->CMAP_format12_Table)
688
690 *glyph_index = 0xffffu;
691 else
692 *glyph_index = 0u;
693
694 if (psc->CMAP_format12_Table)
695 {
698
700
701 group = bsearch(&utf32c, format->groups, GET_BE_DWORD(format->nGroups),
703
704 if (group)
705 {
706 DWORD offset = utf32c - GET_BE_DWORD(group->startCharCode);
707 *glyph_index = GET_BE_DWORD(group->startGlyphID) + offset;
708 return 0;
709 }
710 }
711 return 0;
712}
unsigned char ch[4][2]
Definition: console.c:118
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
short WCHAR
Definition: pedump.c:58
void * CMAP_format12_Table
int groups
Definition: format.c:66
#define bsearch
static VOID * load_CMAP_format12_table(HDC hdc, ScriptCache *psc)
Definition: opentype.c:631
static int __cdecl compare_group(const void *a, const void *b)
Definition: opentype.c:665
#define NtGdiGetGlyphIndicesW(A, B, C, D, E)
Definition: wine-compat.h:3
#define GGI_MARK_NONEXISTING_GLYPHS
Definition: wingdi.h:1085

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 755 of file opentype.c.

756{
757 int i;
758 void *glyph_class_table = NULL;
759
760 if (psc->GDEF_Table)
761 {
762 const GDEF_Header *header = psc->GDEF_Table;
763 WORD offset = GET_BE_WORD( header->GlyphClassDef );
764 if (offset)
765 glyph_class_table = (BYTE *)psc->GDEF_Table + offset;
766 }
767
768 for (i = 0; i < cGlyphs; i++)
769 {
770 WORD class;
771 int char_count = 0;
772 int k;
773
774 k = USP10_FindGlyphInLogClust(pwLogClust, cChars, i);
775 if (k >= 0)
776 {
777 for (; k < cChars && pwLogClust[k] == i; k++)
778 char_count++;
779 }
780
781 class = OT_get_glyph_class( glyph_class_table, pwGlyphs[i] );
782
783 switch (class)
784 {
785 case 0:
786 case BaseGlyph:
787 pGlyphProp[i].sva.fClusterStart = 1;
788 pGlyphProp[i].sva.fDiacritic = 0;
789 pGlyphProp[i].sva.fZeroWidth = 0;
790 break;
791 case LigatureGlyph:
792 pGlyphProp[i].sva.fClusterStart = 1;
793 pGlyphProp[i].sva.fDiacritic = 0;
794 pGlyphProp[i].sva.fZeroWidth = 0;
795 break;
796 case MarkGlyph:
797 pGlyphProp[i].sva.fClusterStart = 0;
798 pGlyphProp[i].sva.fDiacritic = 1;
799 pGlyphProp[i].sva.fZeroWidth = 1;
800 break;
801 case ComponentGlyph:
802 pGlyphProp[i].sva.fClusterStart = 0;
803 pGlyphProp[i].sva.fDiacritic = 0;
804 pGlyphProp[i].sva.fZeroWidth = 0;
805 break;
806 default:
807 ERR("Unknown glyph class %i\n",class);
808 pGlyphProp[i].sva.fClusterStart = 1;
809 pGlyphProp[i].sva.fDiacritic = 0;
810 pGlyphProp[i].sva.fZeroWidth = 0;
811 }
812
813 if (char_count == 0)
814 pGlyphProp[i].sva.fClusterStart = 0;
815 }
816}
int USP10_FindGlyphInLogClust(const WORD *pwLogClust, int cChars, WORD target)
Definition: usp10.c:1015
SCRIPT_VISATTR sva
Definition: usp10.h:215
WORD fClusterStart
Definition: usp10.h:179
_In_ INT _In_ INT cChars
Definition: winddi.h:1486
_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 2914 of file opentype.c.

2915{
2916 int i;
2917 LoadedLanguage *language;
2919 HRESULT rc = S_OK;
2920
2922 if (!(script = usp10_script_cache_get_script(psc, script_tag)))
2923 {
2924 *pcTags = 0;
2925 if (!filtered)
2926 return S_OK;
2927 else
2928 return E_INVALIDARG;
2929 }
2930
2932
2933 language = &script->default_language;
2934 if (language->tag != language_tag || (!language->table[USP10_LANGUAGE_TABLE_GSUB]
2935 && !language->table[USP10_LANGUAGE_TABLE_GPOS]))
2936 language = usp10_script_get_language(script, language_tag);
2937
2938 if (!language)
2939 {
2940 *pcTags = 0;
2941 return S_OK;
2942 }
2943
2944 _initialize_feature_cache(psc, language);
2945
2946 if (tableType)
2947 {
2948 *pcTags = 0;
2949 for (i = 0; i < language->feature_count; i++)
2950 if (language->features[i].tableType == tableType)
2951 *pcTags = (*pcTags)+1;
2952 }
2953 else
2954 *pcTags = language->feature_count;
2955
2956 if (!searchingFor && cMaxTags < *pcTags)
2957 rc = E_OUTOFMEMORY;
2958 else if (searchingFor)
2959 rc = E_INVALIDARG;
2960
2961 for (i = 0; i < language->feature_count; i++)
2962 {
2963 if (i < cMaxTags)
2964 {
2965 if (!tableType || language->features[i].tableType == tableType)
2966 pFeatureTags[i] = language->features[i].tag;
2967 }
2968
2969 if (searchingFor)
2970 {
2971 if ((searchingFor == language->features[i].tag) &&
2972 (!tableType || language->features[i].tableType == tableType))
2973 {
2974 pFeatureTags[0] = language->features[i].tag;
2975 *pcTags = 1;
2976 if (feature)
2977 *feature = &language->features[i];
2978 rc = S_OK;
2979 break;
2980 }
2981 }
2982 }
2983 return rc;
2984}
#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:1807
OPENTYPE_TAG tag
OPENTYPE_TAG tag
LoadedFeature * features
static void _initialize_script_cache(ScriptCache *script_cache)
Definition: opentype.c:2670
static void _initialize_language_cache(LoadedScript *script)
Definition: opentype.c:2788
static LoadedScript * usp10_script_cache_get_script(ScriptCache *script_cache, OPENTYPE_TAG tag)
Definition: opentype.c:2627
static void _initialize_feature_cache(ScriptCache *psc, LoadedLanguage *language)
Definition: opentype.c:2889
static LoadedLanguage * usp10_script_get_language(LoadedScript *script, OPENTYPE_TAG tag)
Definition: opentype.c:2737

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 2803 of file opentype.c.

2804{
2805 int i;
2806 HRESULT rc = S_OK;
2808
2810 if (!(script = usp10_script_cache_get_script(psc, script_tag)))
2811 return E_INVALIDARG;
2812
2814
2815 if (!searchingFor && cMaxTags < script->language_count)
2816 rc = E_OUTOFMEMORY;
2817 else if (searchingFor)
2818 rc = E_INVALIDARG;
2819
2820 *pcTags = script->language_count;
2821
2822 for (i = 0; i < script->language_count; i++)
2823 {
2824 if (i < cMaxTags)
2825 pLanguageTags[i] = script->languages[i].tag;
2826
2827 if (searchingFor)
2828 {
2829 if (searchingFor == script->languages[i].tag)
2830 {
2831 pLanguageTags[0] = script->languages[i].tag;
2832 *pcTags = 1;
2833 rc = S_OK;
2834 break;
2835 }
2836 }
2837 }
2838
2839 if (script->default_language.table[USP10_LANGUAGE_TABLE_GSUB])
2840 {
2841 if (i < cMaxTags)
2842 pLanguageTags[i] = script->default_language.tag;
2843
2844 if (searchingFor && FAILED(rc))
2845 {
2846 pLanguageTags[0] = script->default_language.tag;
2847 }
2848 i++;
2849 *pcTags = (*pcTags) + 1;
2850 }
2851
2852 return rc;
2853}
#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 2689 of file opentype.c.

2690{
2691 int i;
2692 const LoadedScript *script;
2693 HRESULT rc = S_OK;
2694
2696
2697 *pcTags = psc->script_count;
2698
2699 if (searchingFor)
2700 {
2701 if (!(script = usp10_script_cache_get_script(psc, searchingFor)))
2703
2704 *pScriptTags = script->tag;
2705 *pcTags = 1;
2706 return S_OK;
2707 }
2708
2709 if (cMaxTags < *pcTags)
2710 rc = E_OUTOFMEMORY;
2711
2712 cMaxTags = min(cMaxTags, psc->script_count);
2713 for (i = 0; i < cMaxTags; ++i)
2714 {
2715 pScriptTags[i] = psc->scripts[i].tag;
2716 }
2717 return rc;
2718}
#define min(a, b)
Definition: monoChain.cc:55
OPENTYPE_TAG tag
SIZE_T script_count
LoadedScript * scripts
#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 718 of file opentype.c.

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

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 2855 of file opentype.c.

2857{
2858 unsigned int count = GET_BE_WORD(lang->FeatureCount);
2859 unsigned int i, j;
2860
2861 TRACE("table_type %#x, %u features.\n", table_type, count);
2862
2863 if (!count || !usp10_array_reserve((void **)&language->features, &language->features_size,
2864 language->feature_count + count, sizeof(*language->features)))
2865 return;
2866
2867 for (i = 0; i < count; ++i)
2868 {
2869 const OT_FeatureRecord *record;
2870 LoadedFeature *loaded_feature;
2871 const OT_Feature *feature;
2872
2873 record = &feature_list->FeatureRecord[GET_BE_WORD(lang->FeatureIndex[i])];
2874 feature = (const OT_Feature *)((const BYTE *)feature_list + GET_BE_WORD(record->Feature));
2875
2876 loaded_feature = &language->features[language->feature_count + i];
2877 loaded_feature->tag = MS_MAKE_TAG(record->FeatureTag[0], record->FeatureTag[1],
2878 record->FeatureTag[2], record->FeatureTag[3]);
2879 loaded_feature->tableType = table_type;
2880 loaded_feature->feature = feature;
2881 loaded_feature->lookup_count = GET_BE_WORD(feature->LookupCount);
2882 loaded_feature->lookups = calloc(loaded_feature->lookup_count, sizeof(*loaded_feature->lookups));
2883 for (j = 0; j < loaded_feature->lookup_count; ++j)
2884 loaded_feature->lookups[j] = GET_BE_WORD(feature->LookupListIndex[j]);
2885 }
2886 language->feature_count += count;
2887}
#define MS_MAKE_TAG(ch0, ch1, ch2, ch3)
Definition: font.c:112
BOOL usp10_array_reserve(void **elements, SIZE_T *capacity, SIZE_T count, SIZE_T size)
Definition: usp10.c:655
#define calloc
Definition: rosglue.h:14
const void * feature
OT_FeatureRecord FeatureRecord[1]
Definition: opentype.c:182

Referenced by _initialize_feature_cache().

◆ usp10_script_add_language()

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

Definition at line 2720 of file opentype.c.

2721{
2722 LoadedLanguage *language;
2723
2724 if (!usp10_array_reserve((void **)&script->languages, &script->languages_size,
2725 script->language_count + 1, sizeof(*script->languages)))
2726 {
2727 ERR("Failed to grow languages array.\n");
2728 return NULL;
2729 }
2730
2731 language = &script->languages[script->language_count++];
2732 language->tag = tag;
2733
2734 return language;
2735}
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 2750 of file opentype.c.

2752{
2753 SIZE_T initial_count, count, i;
2754 LoadedLanguage *language;
2756 DWORD offset;
2757
2758 TRACE("script %p, table %#x, list %p.\n", script, table, list);
2759
2760 if ((offset = GET_BE_WORD(list->DefaultLangSys)))
2761 {
2762 script->default_language.tag = MS_MAKE_TAG('d','f','l','t');
2763 script->default_language.table[table] = (const BYTE *)list + offset;
2764 TRACE("Default language %p.\n", script->default_language.table[table]);
2765 }
2766
2767 if (!(count = GET_BE_WORD(list->LangSysCount)))
2768 return;
2769
2770 TRACE("Adding %Iu languages.\n", count);
2771
2772 initial_count = script->language_count;
2773 for (i = 0; i < count; ++i)
2774 {
2775 tag = MS_MAKE_TAG(list->LangSysRecord[i].LangSysTag[0],
2776 list->LangSysRecord[i].LangSysTag[1],
2777 list->LangSysRecord[i].LangSysTag[2],
2778 list->LangSysRecord[i].LangSysTag[3]);
2779
2780 if (!(initial_count && (language = usp10_script_get_language(script, tag)))
2781 && !(language = usp10_script_add_language(script, tag)))
2782 return;
2783
2784 language->table[table] = (const BYTE *)list + GET_BE_WORD(list->LangSysRecord[i].LangSys);
2785 }
2786}
ULONG_PTR SIZE_T
Definition: typedefs.h:80
ULONG OPENTYPE_TAG
Definition: usp10.h:205
static LoadedLanguage * usp10_script_add_language(LoadedScript *script, OPENTYPE_TAG tag)
Definition: opentype.c:2720

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 2610 of file opentype.c.

2611{
2613
2614 if (!usp10_array_reserve((void **)&script_cache->scripts, &script_cache->scripts_size,
2615 script_cache->script_count + 1, sizeof(*script_cache->scripts)))
2616 {
2617 ERR("Failed to grow scripts array.\n");
2618 return NULL;
2619 }
2620
2621 script = &script_cache->scripts[script_cache->script_count++];
2622 script->tag = tag;
2623
2624 return script;
2625}
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 2640 of file opentype.c.

2642{
2643 SIZE_T initial_count, count, i;
2646
2647 TRACE("script_cache %p, table %#x, list %p.\n", script_cache, table, list);
2648
2649 if (!(count = GET_BE_WORD(list->ScriptCount)))
2650 return;
2651
2652 TRACE("Adding %Iu scripts.\n", count);
2653
2654 initial_count = script_cache->script_count;
2655 for (i = 0; i < count; ++i)
2656 {
2657 tag = MS_MAKE_TAG(list->ScriptRecord[i].ScriptTag[0],
2658 list->ScriptRecord[i].ScriptTag[1],
2659 list->ScriptRecord[i].ScriptTag[2],
2660 list->ScriptRecord[i].ScriptTag[3]);
2661
2662 if (!(initial_count && (script = usp10_script_cache_get_script(script_cache, tag)))
2663 && !(script = usp10_script_cache_add_script(script_cache, tag)))
2664 return;
2665
2666 script->table[table] = (const BYTE *)list + GET_BE_WORD(list->ScriptRecord[i].Script);
2667 }
2668}
static LoadedScript * usp10_script_cache_add_script(ScriptCache *script_cache, OPENTYPE_TAG tag)
Definition: opentype.c:2610

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 2627 of file opentype.c.

2628{
2629 size_t i;
2630
2631 for (i = 0; i < script_cache->script_count; ++i)
2632 {
2633 if (script_cache->scripts[i].tag == tag)
2634 return &script_cache->scripts[i];
2635 }
2636
2637 return NULL;
2638}

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 2737 of file opentype.c.

2738{
2739 size_t i;
2740
2741 for (i = 0; i < script->language_count; ++i)
2742 {
2743 if (script->languages[i].tag == tag)
2744 return &script->languages[i];
2745 }
2746
2747 return NULL;
2748}

Referenced by OpenType_GetFontFeatureTags(), and usp10_script_add_language_list().

◆ WINE_DEFAULT_DEBUG_CHANNEL()

WINE_DEFAULT_DEBUG_CHANNEL ( uniscribe  )