Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
6b0623fb
Commit
6b0623fb
authored
Jan 25, 2015
by
Nikolay Sivov
Committed by
Alexandre Julliard
Jan 26, 2015
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
dwrite: Initial implementation of GetTypographicFeatures().
parent
fa804252
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
274 additions
and
111 deletions
+274
-111
analyzer.c
dlls/dwrite/analyzer.c
+140
-109
dwrite_private.h
dlls/dwrite/dwrite_private.h
+1
-0
opentype.c
dlls/dwrite/opentype.c
+131
-0
analyzer.c
dlls/dwrite/tests/analyzer.c
+2
-2
No files found.
dlls/dwrite/analyzer.c
View file @
6b0623fb
...
...
@@ -31,138 +31,143 @@ extern const unsigned short wine_scripts_table[];
struct
dwritescript_properties
{
DWRITE_SCRIPT_PROPERTIES
props
;
UINT32
scripttag
;
/* OpenType script tag */
UINT32
scriptalttag
;
/* Version 2 tag, 0 is not defined */
BOOL
is_complex
;
const
struct
scriptshaping_ops
*
ops
;
};
#define _OT(a,b,c,d) DWRITE_MAKE_OPENTYPE_TAG(a,b,c,d)
/* NOTE: keep this array synced with script ids from scripts.h */
static
const
struct
dwritescript_properties
dwritescripts_properties
[
Script_LastId
+
1
]
=
{
{
/* Zzzz */
{
0x7a7a7a5a
,
999
,
15
,
0x0020
,
0
,
0
,
0
,
0
,
0
,
0
,
0
}
},
{
/* Zyyy */
{
0x7979795a
,
998
,
1
,
0x0020
,
0
,
1
,
1
,
0
,
0
,
0
,
0
}
},
{
/* Arab */
{
0x62617241
,
160
,
8
,
0x0640
,
0
,
1
,
0
,
0
,
0
,
1
,
1
},
TRUE
},
{
/* Armn */
{
0x6e6d7241
,
230
,
1
,
0x0020
,
0
,
1
,
1
,
0
,
0
,
0
,
0
}
},
{
/* Avst */
{
0x74737641
,
134
,
8
,
0x0020
,
0
,
1
,
1
,
0
,
0
,
0
,
0
}
},
{
/* Bali */
{
0x696c6142
,
360
,
15
,
0x0020
,
1
,
0
,
1
,
0
,
0
,
0
,
0
}
},
{
/* Bamu */
{
0x756d6142
,
435
,
8
,
0x0020
,
1
,
1
,
1
,
0
,
0
,
0
,
0
}
},
{
/* Arab */
{
0x62617241
,
160
,
8
,
0x0640
,
0
,
1
,
0
,
0
,
0
,
1
,
1
},
_OT
(
'a'
,
'r'
,
'a'
,
'b'
),
0
,
TRUE
},
{
/* Armn */
{
0x6e6d7241
,
230
,
1
,
0x0020
,
0
,
1
,
1
,
0
,
0
,
0
,
0
}
,
_OT
(
'a'
,
'r'
,
'm'
,
'n'
)
},
{
/* Avst */
{
0x74737641
,
134
,
8
,
0x0020
,
0
,
1
,
1
,
0
,
0
,
0
,
0
}
,
_OT
(
'a'
,
'v'
,
's'
,
't'
)
},
{
/* Bali */
{
0x696c6142
,
360
,
15
,
0x0020
,
1
,
0
,
1
,
0
,
0
,
0
,
0
}
,
_OT
(
'b'
,
'a'
,
'l'
,
'i'
)
},
{
/* Bamu */
{
0x756d6142
,
435
,
8
,
0x0020
,
1
,
1
,
1
,
0
,
0
,
0
,
0
}
,
_OT
(
'b'
,
'a'
,
'm'
,
'u'
)
},
{
/* Bass */
{
0x73736142
,
259
,
1
,
0x0020
,
0
,
0
,
0
,
0
,
0
,
0
,
0
}
},
{
/* Batk */
{
0x6b746142
,
365
,
8
,
0x0020
,
0
,
1
,
1
,
0
,
0
,
0
,
0
}
},
{
/* Beng */
{
0x676e6542
,
325
,
15
,
0x0020
,
1
,
1
,
0
,
0
,
0
,
1
,
0
},
TRUE
},
{
/* Bopo */
{
0x6f706f42
,
285
,
1
,
0x0020
,
0
,
0
,
1
,
1
,
0
,
0
,
0
}
},
{
/* Brah */
{
0x68617242
,
300
,
8
,
0x0020
,
0
,
1
,
1
,
0
,
0
,
0
,
0
}
},
{
/* Brai */
{
0x69617242
,
570
,
1
,
0x0020
,
0
,
1
,
1
,
0
,
0
,
0
,
0
},
TRUE
},
{
/* Bugi */
{
0x69677542
,
367
,
8
,
0x0020
,
0
,
1
,
1
,
0
,
0
,
0
,
0
}
},
{
/* Buhd */
{
0x64687542
,
372
,
8
,
0x0020
,
0
,
0
,
1
,
0
,
0
,
0
,
0
}
},
{
/* Cans */
{
0x736e6143
,
440
,
1
,
0x0020
,
0
,
1
,
1
,
0
,
0
,
0
,
0
},
TRUE
},
{
/* Cari */
{
0x69726143
,
201
,
1
,
0x0020
,
0
,
0
,
1
,
0
,
0
,
0
,
0
}
},
{
/* Batk */
{
0x6b746142
,
365
,
8
,
0x0020
,
0
,
1
,
1
,
0
,
0
,
0
,
0
}
,
_OT
(
'b'
,
'a'
,
't'
,
'k'
)
},
{
/* Beng */
{
0x676e6542
,
325
,
15
,
0x0020
,
1
,
1
,
0
,
0
,
0
,
1
,
0
},
_OT
(
'b'
,
'e'
,
'n'
,
'g'
),
_OT
(
'b'
,
'n'
,
'g'
,
'2'
),
TRUE
},
{
/* Bopo */
{
0x6f706f42
,
285
,
1
,
0x0020
,
0
,
0
,
1
,
1
,
0
,
0
,
0
}
,
_OT
(
'b'
,
'o'
,
'p'
,
'o'
)
},
{
/* Brah */
{
0x68617242
,
300
,
8
,
0x0020
,
0
,
1
,
1
,
0
,
0
,
0
,
0
}
,
_OT
(
'b'
,
'r'
,
'a'
,
'h'
)
},
{
/* Brai */
{
0x69617242
,
570
,
1
,
0x0020
,
0
,
1
,
1
,
0
,
0
,
0
,
0
},
_OT
(
'b'
,
'r'
,
'a'
,
'i'
),
0
,
TRUE
},
{
/* Bugi */
{
0x69677542
,
367
,
8
,
0x0020
,
0
,
1
,
1
,
0
,
0
,
0
,
0
}
,
_OT
(
'b'
,
'u'
,
'g'
,
'i'
)
},
{
/* Buhd */
{
0x64687542
,
372
,
8
,
0x0020
,
0
,
0
,
1
,
0
,
0
,
0
,
0
}
,
_OT
(
'b'
,
'u'
,
'h'
,
'd'
)
},
{
/* Cans */
{
0x736e6143
,
440
,
1
,
0x0020
,
0
,
1
,
1
,
0
,
0
,
0
,
0
},
_OT
(
'c'
,
'a'
,
'n'
,
's'
),
0
,
TRUE
},
{
/* Cari */
{
0x69726143
,
201
,
1
,
0x0020
,
0
,
0
,
1
,
0
,
0
,
0
,
0
}
,
_OT
(
'c'
,
'a'
,
'r'
,
'i'
)
},
{
/* Aghb */
{
0x62686741
,
239
,
1
,
0x0020
,
0
,
0
,
0
,
0
,
0
,
0
,
0
}
},
{
/* Cakm */
{
0x6d6b6143
,
349
,
1
,
0x0020
,
0
,
0
,
0
,
0
,
0
,
0
,
0
}
},
{
/* Cham */
{
0x6d616843
,
358
,
8
,
0x0020
,
1
,
1
,
1
,
0
,
0
,
0
,
0
}
},
{
/* Cher */
{
0x72656843
,
445
,
1
,
0x0020
,
0
,
1
,
1
,
0
,
0
,
0
,
0
},
TRUE
},
{
/* Copt */
{
0x74706f43
,
204
,
8
,
0x0020
,
0
,
1
,
1
,
0
,
0
,
0
,
0
}
},
{
/* Xsux */
{
0x78757358
,
20
,
1
,
0x0020
,
0
,
0
,
1
,
1
,
0
,
0
,
0
}
},
{
/* Cprt */
{
0x74727043
,
403
,
1
,
0x0020
,
0
,
0
,
1
,
0
,
0
,
0
,
0
}
},
{
/* Cyrl */
{
0x6c727943
,
220
,
8
,
0x0020
,
0
,
1
,
1
,
0
,
0
,
0
,
0
}
},
{
/* Dsrt */
{
0x74727344
,
250
,
1
,
0x0020
,
0
,
1
,
1
,
0
,
0
,
0
,
0
},
TRUE
},
{
/* Deva */
{
0x61766544
,
315
,
15
,
0x0020
,
1
,
1
,
0
,
0
,
0
,
1
,
0
},
TRUE
},
{
/* Cakm */
{
0x6d6b6143
,
349
,
1
,
0x0020
,
0
,
0
,
0
,
0
,
0
,
0
,
0
}
,
_OT
(
'c'
,
'a'
,
'k'
,
'm'
)
},
{
/* Cham */
{
0x6d616843
,
358
,
8
,
0x0020
,
1
,
1
,
1
,
0
,
0
,
0
,
0
}
,
_OT
(
'c'
,
'h'
,
'a'
,
'm'
)
},
{
/* Cher */
{
0x72656843
,
445
,
1
,
0x0020
,
0
,
1
,
1
,
0
,
0
,
0
,
0
},
_OT
(
'c'
,
'h'
,
'e'
,
'r'
),
0
,
TRUE
},
{
/* Copt */
{
0x74706f43
,
204
,
8
,
0x0020
,
0
,
1
,
1
,
0
,
0
,
0
,
0
}
,
_OT
(
'c'
,
'o'
,
'p'
,
't'
)
},
{
/* Xsux */
{
0x78757358
,
20
,
1
,
0x0020
,
0
,
0
,
1
,
1
,
0
,
0
,
0
}
,
_OT
(
'x'
,
's'
,
'u'
,
'x'
)
},
{
/* Cprt */
{
0x74727043
,
403
,
1
,
0x0020
,
0
,
0
,
1
,
0
,
0
,
0
,
0
}
,
_OT
(
'c'
,
'p'
,
'r'
,
't'
)
},
{
/* Cyrl */
{
0x6c727943
,
220
,
8
,
0x0020
,
0
,
1
,
1
,
0
,
0
,
0
,
0
}
,
_OT
(
'c'
,
'y'
,
'r'
,
'l'
)
},
{
/* Dsrt */
{
0x74727344
,
250
,
1
,
0x0020
,
0
,
1
,
1
,
0
,
0
,
0
,
0
},
_OT
(
'd'
,
's'
,
'r'
,
't'
),
0
,
TRUE
},
{
/* Deva */
{
0x61766544
,
315
,
15
,
0x0020
,
1
,
1
,
0
,
0
,
0
,
1
,
0
},
_OT
(
'd'
,
'e'
,
'v'
,
'a'
),
_OT
(
'd'
,
'e'
,
'v'
,
'2'
),
TRUE
},
{
/* Dupl */
{
0x6c707544
,
755
,
1
,
0x0020
,
0
,
0
,
0
,
0
,
0
,
0
,
0
}
},
{
/* Egyp */
{
0x70796745
,
50
,
1
,
0x0020
,
0
,
0
,
1
,
1
,
0
,
0
,
0
}
},
{
/* Egyp */
{
0x70796745
,
50
,
1
,
0x0020
,
0
,
0
,
1
,
1
,
0
,
0
,
0
}
,
_OT
(
'e'
,
'g'
,
'y'
,
'p'
)
},
{
/* Elba */
{
0x61626c45
,
226
,
1
,
0x0020
,
0
,
0
,
0
,
0
,
0
,
0
,
0
}
},
{
/* Ethi */
{
0x69687445
,
430
,
8
,
0x0020
,
0
,
1
,
1
,
0
,
0
,
0
,
0
},
TRUE
},
{
/* Geor */
{
0x726f6547
,
240
,
1
,
0x0020
,
0
,
1
,
1
,
0
,
0
,
0
,
0
}
},
{
/* Glag */
{
0x67616c47
,
225
,
1
,
0x0020
,
0
,
1
,
1
,
0
,
0
,
0
,
0
}
},
{
/* Goth */
{
0x68746f47
,
206
,
1
,
0x0020
,
0
,
1
,
1
,
0
,
0
,
0
,
0
}
},
{
/* Ethi */
{
0x69687445
,
430
,
8
,
0x0020
,
0
,
1
,
1
,
0
,
0
,
0
,
0
},
_OT
(
'e'
,
't'
,
'h'
,
'i'
),
0
,
TRUE
},
{
/* Geor */
{
0x726f6547
,
240
,
1
,
0x0020
,
0
,
1
,
1
,
0
,
0
,
0
,
0
}
,
_OT
(
'g'
,
'e'
,
'o'
,
'r'
)
},
{
/* Glag */
{
0x67616c47
,
225
,
1
,
0x0020
,
0
,
1
,
1
,
0
,
0
,
0
,
0
}
,
_OT
(
'g'
,
'l'
,
'a'
,
'g'
)
},
{
/* Goth */
{
0x68746f47
,
206
,
1
,
0x0020
,
0
,
1
,
1
,
0
,
0
,
0
,
0
}
,
_OT
(
'g'
,
'o'
,
't'
,
'h'
)
},
{
/* Gran */
{
0x6e617247
,
343
,
1
,
0x0020
,
0
,
0
,
0
,
0
,
0
,
0
,
0
}
},
{
/* Grek */
{
0x6b657247
,
200
,
1
,
0x0020
,
0
,
1
,
1
,
0
,
0
,
0
,
0
}
},
{
/* Gujr */
{
0x726a7547
,
320
,
15
,
0x0020
,
1
,
1
,
1
,
0
,
0
,
0
,
0
},
TRUE
},
{
/* Guru */
{
0x75727547
,
310
,
15
,
0x0020
,
1
,
1
,
0
,
0
,
0
,
1
,
0
},
TRUE
},
{
/* Hani */
{
0x696e6148
,
500
,
8
,
0x0020
,
0
,
0
,
1
,
1
,
0
,
0
,
0
}
},
{
/* Hang */
{
0x676e6148
,
286
,
8
,
0x0020
,
1
,
1
,
1
,
1
,
0
,
0
,
0
},
TRUE
},
{
/* Hano */
{
0x6f6e6148
,
371
,
8
,
0x0020
,
0
,
0
,
1
,
0
,
0
,
0
,
0
}
},
{
/* Hebr */
{
0x72626548
,
125
,
8
,
0x0020
,
1
,
1
,
1
,
0
,
0
,
0
,
0
},
TRUE
},
{
/* Hira */
{
0x61726948
,
410
,
8
,
0x0020
,
0
,
0
,
1
,
1
,
0
,
0
,
0
}
},
{
/* Armi */
{
0x696d7241
,
124
,
1
,
0x0020
,
0
,
1
,
1
,
0
,
0
,
0
,
0
}
},
{
/* Phli */
{
0x696c6850
,
131
,
1
,
0x0020
,
0
,
1
,
1
,
0
,
0
,
0
,
0
}
},
{
/* Prti */
{
0x69747250
,
130
,
1
,
0x0020
,
0
,
1
,
1
,
0
,
0
,
0
,
0
}
},
{
/* Java */
{
0x6176614a
,
361
,
15
,
0x0020
,
1
,
0
,
1
,
0
,
0
,
0
,
0
}
},
{
/* Kthi */
{
0x6968744b
,
317
,
15
,
0x0020
,
1
,
1
,
0
,
0
,
0
,
1
,
0
}
},
{
/* Knda */
{
0x61646e4b
,
345
,
15
,
0x0020
,
1
,
1
,
1
,
0
,
0
,
0
,
0
},
TRUE
},
{
/* Kana */
{
0x616e614b
,
411
,
8
,
0x0020
,
0
,
0
,
1
,
1
,
0
,
0
,
0
}
},
{
/* Kali */
{
0x696c614b
,
357
,
8
,
0x0020
,
0
,
1
,
1
,
0
,
0
,
0
,
0
}
},
{
/* Khar */
{
0x7261684b
,
305
,
15
,
0x0020
,
1
,
0
,
1
,
0
,
0
,
0
,
0
}
},
{
/* Khmr */
{
0x726d684b
,
355
,
8
,
0x0020
,
1
,
0
,
1
,
0
,
1
,
0
,
0
},
TRUE
},
{
/* Grek */
{
0x6b657247
,
200
,
1
,
0x0020
,
0
,
1
,
1
,
0
,
0
,
0
,
0
}
,
_OT
(
'g'
,
'r'
,
'e'
,
'k'
)
},
{
/* Gujr */
{
0x726a7547
,
320
,
15
,
0x0020
,
1
,
1
,
1
,
0
,
0
,
0
,
0
},
_OT
(
'g'
,
'u'
,
'j'
,
'r'
),
_OT
(
'g'
,
'j'
,
'r'
,
'2'
),
TRUE
},
{
/* Guru */
{
0x75727547
,
310
,
15
,
0x0020
,
1
,
1
,
0
,
0
,
0
,
1
,
0
},
_OT
(
'g'
,
'u'
,
'r'
,
'u'
),
_OT
(
'g'
,
'u'
,
'r'
,
'2'
),
TRUE
},
{
/* Hani */
{
0x696e6148
,
500
,
8
,
0x0020
,
0
,
0
,
1
,
1
,
0
,
0
,
0
}
,
_OT
(
'h'
,
'a'
,
'n'
,
'i'
)
},
{
/* Hang */
{
0x676e6148
,
286
,
8
,
0x0020
,
1
,
1
,
1
,
1
,
0
,
0
,
0
},
_OT
(
'h'
,
'a'
,
'n'
,
'g'
),
0
,
TRUE
},
{
/* Hano */
{
0x6f6e6148
,
371
,
8
,
0x0020
,
0
,
0
,
1
,
0
,
0
,
0
,
0
}
,
_OT
(
'h'
,
'a'
,
'n'
,
'o'
)
},
{
/* Hebr */
{
0x72626548
,
125
,
8
,
0x0020
,
1
,
1
,
1
,
0
,
0
,
0
,
0
},
_OT
(
'h'
,
'e'
,
'b'
,
'r'
),
0
,
TRUE
},
{
/* Hira */
{
0x61726948
,
410
,
8
,
0x0020
,
0
,
0
,
1
,
1
,
0
,
0
,
0
}
,
_OT
(
'k'
,
'a'
,
'n'
,
'a'
)
},
{
/* Armi */
{
0x696d7241
,
124
,
1
,
0x0020
,
0
,
1
,
1
,
0
,
0
,
0
,
0
}
,
_OT
(
'a'
,
'r'
,
'm'
,
'i'
)
},
{
/* Phli */
{
0x696c6850
,
131
,
1
,
0x0020
,
0
,
1
,
1
,
0
,
0
,
0
,
0
}
,
_OT
(
'p'
,
'h'
,
'l'
,
'i'
)
},
{
/* Prti */
{
0x69747250
,
130
,
1
,
0x0020
,
0
,
1
,
1
,
0
,
0
,
0
,
0
}
,
_OT
(
'p'
,
'r'
,
't'
,
'i'
)
},
{
/* Java */
{
0x6176614a
,
361
,
15
,
0x0020
,
1
,
0
,
1
,
0
,
0
,
0
,
0
}
,
_OT
(
'j'
,
'a'
,
'v'
,
'a'
)
},
{
/* Kthi */
{
0x6968744b
,
317
,
15
,
0x0020
,
1
,
1
,
0
,
0
,
0
,
1
,
0
}
,
_OT
(
'k'
,
't'
,
'h'
,
'i'
)
},
{
/* Knda */
{
0x61646e4b
,
345
,
15
,
0x0020
,
1
,
1
,
1
,
0
,
0
,
0
,
0
},
_OT
(
'k'
,
'n'
,
'd'
,
'a'
),
_OT
(
'k'
,
'n'
,
'd'
,
'2'
),
TRUE
},
{
/* Kana */
{
0x616e614b
,
411
,
8
,
0x0020
,
0
,
0
,
1
,
1
,
0
,
0
,
0
}
,
_OT
(
'k'
,
'a'
,
'n'
,
'a'
)
},
{
/* Kali */
{
0x696c614b
,
357
,
8
,
0x0020
,
0
,
1
,
1
,
0
,
0
,
0
,
0
}
,
_OT
(
'k'
,
'a'
,
'l'
,
'i'
)
},
{
/* Khar */
{
0x7261684b
,
305
,
15
,
0x0020
,
1
,
0
,
1
,
0
,
0
,
0
,
0
}
,
_OT
(
'k'
,
'h'
,
'a'
,
'r'
)
},
{
/* Khmr */
{
0x726d684b
,
355
,
8
,
0x0020
,
1
,
0
,
1
,
0
,
1
,
0
,
0
},
_OT
(
'k'
,
'h'
,
'm'
,
'r'
),
0
,
TRUE
},
{
/* Khoj */
{
0x6a6f684b
,
322
,
1
,
0x0020
,
0
,
0
,
0
,
0
,
0
,
0
,
0
}
},
{
/* Sind */
{
0x646e6953
,
318
,
1
,
0x0020
,
0
,
0
,
0
,
0
,
0
,
0
,
0
}
},
{
/* Laoo */
{
0x6f6f614c
,
356
,
8
,
0x0020
,
1
,
0
,
1
,
0
,
1
,
0
,
0
},
TRUE
},
{
/* Latn */
{
0x6e74614c
,
215
,
1
,
0x0020
,
0
,
1
,
1
,
0
,
0
,
0
,
0
},
FALSE
,
&
latn_shaping_ops
},
{
/* Lepc */
{
0x6370654c
,
335
,
8
,
0x0020
,
1
,
1
,
1
,
0
,
0
,
0
,
0
}
},
{
/* Limb */
{
0x626d694c
,
336
,
8
,
0x0020
,
1
,
1
,
1
,
0
,
0
,
0
,
0
}
},
{
/* Laoo */
{
0x6f6f614c
,
356
,
8
,
0x0020
,
1
,
0
,
1
,
0
,
1
,
0
,
0
},
_OT
(
'l'
,
'a'
,
'o'
,
' '
),
0
,
TRUE
},
{
/* Latn */
{
0x6e74614c
,
215
,
1
,
0x0020
,
0
,
1
,
1
,
0
,
0
,
0
,
0
},
_OT
(
'l'
,
'a'
,
't'
,
'n'
),
0
,
FALSE
,
&
latn_shaping_ops
},
{
/* Lepc */
{
0x6370654c
,
335
,
8
,
0x0020
,
1
,
1
,
1
,
0
,
0
,
0
,
0
}
,
_OT
(
'l'
,
'e'
,
'p'
,
'c'
)
},
{
/* Limb */
{
0x626d694c
,
336
,
8
,
0x0020
,
1
,
1
,
1
,
0
,
0
,
0
,
0
}
,
_OT
(
'l'
,
'i'
,
'm'
,
'b'
)
},
{
/* Lina */
{
0x616e694c
,
400
,
1
,
0x0020
,
0
,
0
,
0
,
0
,
0
,
0
,
0
}
},
{
/* Linb */
{
0x626e694c
,
401
,
1
,
0x0020
,
0
,
0
,
1
,
1
,
0
,
0
,
0
}
},
{
/* Lisu */
{
0x7573694c
,
399
,
1
,
0x0020
,
0
,
1
,
1
,
0
,
0
,
0
,
0
}
},
{
/* Lyci */
{
0x6963794c
,
202
,
1
,
0x0020
,
0
,
1
,
1
,
0
,
0
,
0
,
0
}
},
{
/* Lydi */
{
0x6964794c
,
116
,
1
,
0x0020
,
0
,
1
,
1
,
0
,
0
,
0
,
0
}
},
{
/* Linb */
{
0x626e694c
,
401
,
1
,
0x0020
,
0
,
0
,
1
,
1
,
0
,
0
,
0
}
,
_OT
(
'l'
,
'i'
,
'n'
,
'b'
)
},
{
/* Lisu */
{
0x7573694c
,
399
,
1
,
0x0020
,
0
,
1
,
1
,
0
,
0
,
0
,
0
}
,
_OT
(
'l'
,
'i'
,
's'
,
'u'
)
},
{
/* Lyci */
{
0x6963794c
,
202
,
1
,
0x0020
,
0
,
1
,
1
,
0
,
0
,
0
,
0
}
,
_OT
(
'l'
,
'y'
,
'c'
,
'i'
)
},
{
/* Lydi */
{
0x6964794c
,
116
,
1
,
0x0020
,
0
,
1
,
1
,
0
,
0
,
0
,
0
}
,
_OT
(
'l'
,
'y'
,
'd'
,
'i'
)
},
{
/* Mahj */
{
0x6a68614d
,
314
,
1
,
0x0020
,
0
,
0
,
0
,
0
,
0
,
0
,
0
}
},
{
/* Mlym */
{
0x6d796c4d
,
347
,
15
,
0x0020
,
1
,
1
,
1
,
0
,
0
,
0
,
0
},
TRUE
},
{
/* Mand */
{
0x646e614d
,
140
,
8
,
0x0640
,
0
,
1
,
0
,
0
,
0
,
1
,
1
}
},
{
/* Mlym */
{
0x6d796c4d
,
347
,
15
,
0x0020
,
1
,
1
,
1
,
0
,
0
,
0
,
0
},
_OT
(
'm'
,
'l'
,
'y'
,
'm'
),
_OT
(
'm'
,
'l'
,
'm'
,
'2'
),
TRUE
},
{
/* Mand */
{
0x646e614d
,
140
,
8
,
0x0640
,
0
,
1
,
0
,
0
,
0
,
1
,
1
}
,
_OT
(
'm'
,
'a'
,
'n'
,
'd'
)
},
{
/* Mani */
{
0x696e614d
,
139
,
1
,
0x0020
,
0
,
0
,
0
,
0
,
0
,
0
,
0
}
},
{
/* Mtei */
{
0x6965744d
,
337
,
8
,
0x0020
,
1
,
1
,
1
,
0
,
0
,
0
,
0
}
},
{
/* Mtei */
{
0x6965744d
,
337
,
8
,
0x0020
,
1
,
1
,
1
,
0
,
0
,
0
,
0
}
,
_OT
(
'm'
,
't'
,
'e'
,
'i'
)
},
{
/* Mend */
{
0x646e654d
,
438
,
1
,
0x0020
,
0
,
0
,
0
,
0
,
0
,
0
,
0
}
},
{
/* Merc */
{
0x6372654d
,
101
,
1
,
0x0020
,
0
,
0
,
0
,
0
,
0
,
0
,
0
}
},
{
/* Mero */
{
0x6f72654d
,
100
,
1
,
0x0020
,
0
,
0
,
0
,
0
,
0
,
0
,
0
}
},
{
/* Merc */
{
0x6372654d
,
101
,
1
,
0x0020
,
0
,
0
,
0
,
0
,
0
,
0
,
0
}
,
_OT
(
'm'
,
'e'
,
'r'
,
'c'
)
},
{
/* Mero */
{
0x6f72654d
,
100
,
1
,
0x0020
,
0
,
0
,
0
,
0
,
0
,
0
,
0
}
,
_OT
(
'm'
,
'e'
,
'r'
,
'o'
)
},
{
/* Plrd */
{
0x64726c50
,
282
,
1
,
0x0020
,
0
,
0
,
0
,
0
,
0
,
0
,
0
}
},
{
/* Modi */
{
0x69646f4d
,
324
,
1
,
0x0020
,
0
,
0
,
0
,
0
,
0
,
0
,
0
}
},
{
/* Mong */
{
0x676e6f4d
,
145
,
8
,
0x0020
,
0
,
1
,
0
,
0
,
0
,
1
,
1
},
TRUE
},
{
/* Mong */
{
0x676e6f4d
,
145
,
8
,
0x0020
,
0
,
1
,
0
,
0
,
0
,
1
,
1
},
_OT
(
'm'
,
'o'
,
'n'
,
'g'
),
0
,
TRUE
},
{
/* Mroo */
{
0x6f6f724d
,
199
,
1
,
0x0020
,
0
,
0
,
0
,
0
,
0
,
0
,
0
}
},
{
/* Mymr */
{
0x726d794d
,
350
,
15
,
0x0020
,
1
,
1
,
1
,
0
,
0
,
0
,
0
},
TRUE
},
{
/* Mymr */
{
0x726d794d
,
350
,
15
,
0x0020
,
1
,
1
,
1
,
0
,
0
,
0
,
0
},
_OT
(
'm'
,
'y'
,
'm'
,
'r'
),
0
,
TRUE
},
{
/* Nbat */
{
0x7461624e
,
159
,
1
,
0x0020
,
0
,
0
,
0
,
0
,
0
,
0
,
0
}
},
{
/* Talu */
{
0x756c6154
,
354
,
8
,
0x0020
,
1
,
1
,
1
,
0
,
0
,
0
,
0
},
TRUE
},
{
/* Nkoo */
{
0x6f6f6b4e
,
165
,
8
,
0x0020
,
0
,
1
,
0
,
0
,
0
,
1
,
1
},
TRUE
},
{
/* Ogam */
{
0x6d61674f
,
212
,
1
,
0x1680
,
0
,
1
,
0
,
0
,
0
,
1
,
0
},
TRUE
},
{
/* Olck */
{
0x6b636c4f
,
261
,
1
,
0x0020
,
0
,
1
,
1
,
0
,
0
,
0
,
0
}
},
{
/* Ital */
{
0x6c617449
,
210
,
1
,
0x0020
,
0
,
1
,
1
,
0
,
0
,
0
,
0
}
},
{
/* Talu */
{
0x756c6154
,
354
,
8
,
0x0020
,
1
,
1
,
1
,
0
,
0
,
0
,
0
},
_OT
(
't'
,
'a'
,
'l'
,
'u'
),
0
,
TRUE
},
{
/* Nkoo */
{
0x6f6f6b4e
,
165
,
8
,
0x0020
,
0
,
1
,
0
,
0
,
0
,
1
,
1
},
_OT
(
'n'
,
'k'
,
'o'
,
' '
),
0
,
TRUE
},
{
/* Ogam */
{
0x6d61674f
,
212
,
1
,
0x1680
,
0
,
1
,
0
,
0
,
0
,
1
,
0
},
_OT
(
'o'
,
'g'
,
'a'
,
'm'
),
0
,
TRUE
},
{
/* Olck */
{
0x6b636c4f
,
261
,
1
,
0x0020
,
0
,
1
,
1
,
0
,
0
,
0
,
0
}
,
_OT
(
'o'
,
'l'
,
'c'
,
'k'
)
},
{
/* Ital */
{
0x6c617449
,
210
,
1
,
0x0020
,
0
,
1
,
1
,
0
,
0
,
0
,
0
}
,
_OT
(
'i'
,
't'
,
'a'
,
'l'
)
},
{
/* Narb */
{
0x6272614e
,
106
,
1
,
0x0020
,
0
,
0
,
0
,
0
,
0
,
0
,
0
}
},
{
/* Perm */
{
0x6d726550
,
227
,
1
,
0x0020
,
0
,
0
,
0
,
0
,
0
,
0
,
0
}
},
{
/* Xpeo */
{
0x6f657058
,
30
,
1
,
0x0020
,
0
,
1
,
1
,
1
,
0
,
0
,
0
},
TRUE
},
{
/* Sarb */
{
0x62726153
,
105
,
1
,
0x0020
,
0
,
1
,
1
,
0
,
0
,
0
,
0
}
},
{
/* Orkh */
{
0x686b724f
,
175
,
1
,
0x0020
,
0
,
1
,
1
,
0
,
0
,
0
,
0
}
},
{
/* Orya */
{
0x6179724f
,
327
,
15
,
0x0020
,
1
,
1
,
1
,
0
,
0
,
0
,
0
},
TRUE
},
{
/* Osma */
{
0x616d734f
,
260
,
8
,
0x0020
,
0
,
1
,
1
,
0
,
0
,
0
,
0
},
TRUE
},
{
/* Xpeo */
{
0x6f657058
,
30
,
1
,
0x0020
,
0
,
1
,
1
,
1
,
0
,
0
,
0
},
_OT
(
'x'
,
'p'
,
'e'
,
'o'
),
0
,
TRUE
},
{
/* Sarb */
{
0x62726153
,
105
,
1
,
0x0020
,
0
,
1
,
1
,
0
,
0
,
0
,
0
}
,
_OT
(
's'
,
'a'
,
'r'
,
'b'
)
},
{
/* Orkh */
{
0x686b724f
,
175
,
1
,
0x0020
,
0
,
1
,
1
,
0
,
0
,
0
,
0
}
,
_OT
(
'o'
,
'r'
,
'k'
,
'h'
)
},
{
/* Orya */
{
0x6179724f
,
327
,
15
,
0x0020
,
1
,
1
,
1
,
0
,
0
,
0
,
0
},
_OT
(
'o'
,
'r'
,
'y'
,
'a'
),
_OT
(
'o'
,
'r'
,
'y'
,
'2'
),
TRUE
},
{
/* Osma */
{
0x616d734f
,
260
,
8
,
0x0020
,
0
,
1
,
1
,
0
,
0
,
0
,
0
},
_OT
(
'o'
,
's'
,
'm'
,
'a'
),
0
,
TRUE
},
{
/* Hmng */
{
0x676e6d48
,
450
,
1
,
0x0020
,
0
,
0
,
0
,
0
,
0
,
0
,
0
}
},
{
/* Palm */
{
0x6d6c6150
,
126
,
1
,
0x0020
,
0
,
0
,
0
,
0
,
0
,
0
,
0
}
},
{
/* Pauc */
{
0x63756150
,
263
,
1
,
0x0020
,
0
,
0
,
0
,
0
,
0
,
0
,
0
}
},
{
/* Phag */
{
0x67616850
,
331
,
8
,
0x0020
,
0
,
1
,
0
,
0
,
0
,
1
,
1
},
TRUE
},
{
/* Phnx */
{
0x786e6850
,
115
,
1
,
0x0020
,
0
,
0
,
1
,
0
,
0
,
0
,
0
}
},
{
/* Phag */
{
0x67616850
,
331
,
8
,
0x0020
,
0
,
1
,
0
,
0
,
0
,
1
,
1
},
_OT
(
'p'
,
'h'
,
'a'
,
'g'
),
0
,
TRUE
},
{
/* Phnx */
{
0x786e6850
,
115
,
1
,
0x0020
,
0
,
0
,
1
,
0
,
0
,
0
,
0
}
,
_OT
(
'p'
,
'h'
,
'n'
,
'x'
)
},
{
/* Phlp */
{
0x706c6850
,
132
,
1
,
0x0020
,
0
,
0
,
0
,
0
,
0
,
0
,
0
}
},
{
/* Rjng */
{
0x676e6a52
,
363
,
8
,
0x0020
,
1
,
0
,
1
,
0
,
0
,
0
,
0
}
},
{
/* Runr */
{
0x726e7552
,
211
,
1
,
0x0020
,
0
,
0
,
1
,
0
,
0
,
0
,
0
},
TRUE
},
{
/* Samr */
{
0x726d6153
,
123
,
8
,
0x0020
,
0
,
1
,
1
,
0
,
0
,
0
,
0
}
},
{
/* Saur */
{
0x72756153
,
344
,
8
,
0x0020
,
1
,
1
,
1
,
0
,
0
,
0
,
0
}
},
{
/* Shrd */
{
0x64726853
,
319
,
1
,
0x0020
,
0
,
0
,
0
,
0
,
0
,
0
,
0
}
},
{
/* Shaw */
{
0x77616853
,
281
,
1
,
0x0020
,
0
,
1
,
1
,
0
,
0
,
0
,
0
}
},
{
/* Rjng */
{
0x676e6a52
,
363
,
8
,
0x0020
,
1
,
0
,
1
,
0
,
0
,
0
,
0
}
,
_OT
(
'r'
,
'j'
,
'n'
,
'g'
)
},
{
/* Runr */
{
0x726e7552
,
211
,
1
,
0x0020
,
0
,
0
,
1
,
0
,
0
,
0
,
0
},
_OT
(
'r'
,
'u'
,
'n'
,
'r'
),
0
,
TRUE
},
{
/* Samr */
{
0x726d6153
,
123
,
8
,
0x0020
,
0
,
1
,
1
,
0
,
0
,
0
,
0
}
,
_OT
(
's'
,
'a'
,
'm'
,
'r'
)
},
{
/* Saur */
{
0x72756153
,
344
,
8
,
0x0020
,
1
,
1
,
1
,
0
,
0
,
0
,
0
}
,
_OT
(
's'
,
'a'
,
'u'
,
'r'
)
},
{
/* Shrd */
{
0x64726853
,
319
,
1
,
0x0020
,
0
,
0
,
0
,
0
,
0
,
0
,
0
}
,
_OT
(
's'
,
'h'
,
'r'
,
'd'
)
},
{
/* Shaw */
{
0x77616853
,
281
,
1
,
0x0020
,
0
,
1
,
1
,
0
,
0
,
0
,
0
}
,
_OT
(
's'
,
'h'
,
'a'
,
'w'
)
},
{
/* Sidd */
{
0x64646953
,
302
,
1
,
0x0020
,
0
,
0
,
0
,
0
,
0
,
0
,
0
}
},
{
/* Sinh */
{
0x686e6953
,
348
,
8
,
0x0020
,
1
,
1
,
1
,
0
,
0
,
0
,
0
},
TRUE
},
{
/* Sora */
{
0x61726f53
,
398
,
1
,
0x0020
,
0
,
0
,
0
,
0
,
0
,
0
,
0
}
},
{
/* Sund */
{
0x646e7553
,
362
,
8
,
0x0020
,
1
,
1
,
1
,
0
,
0
,
0
,
0
}
},
{
/* Sylo */
{
0x6f6c7953
,
316
,
8
,
0x0020
,
1
,
1
,
0
,
0
,
0
,
1
,
0
}
},
{
/* Syrc */
{
0x63727953
,
135
,
8
,
0x0640
,
0
,
1
,
0
,
0
,
0
,
1
,
1
},
TRUE
},
{
/* Tglg */
{
0x676c6754
,
370
,
8
,
0x0020
,
0
,
1
,
1
,
0
,
0
,
0
,
0
}
},
{
/* Tagb */
{
0x62676154
,
373
,
8
,
0x0020
,
0
,
1
,
1
,
0
,
0
,
0
,
0
}
},
{
/* Tale */
{
0x656c6154
,
353
,
1
,
0x0020
,
0
,
1
,
1
,
0
,
0
,
0
,
0
},
TRUE
},
{
/* Lana */
{
0x616e614c
,
351
,
8
,
0x0020
,
1
,
0
,
1
,
0
,
0
,
0
,
0
}
},
{
/* Tavt */
{
0x74766154
,
359
,
8
,
0x0020
,
1
,
0
,
1
,
0
,
1
,
0
,
0
}
},
{
/* Takr */
{
0x726b6154
,
321
,
1
,
0x0020
,
0
,
0
,
0
,
0
,
0
,
0
,
0
}
},
{
/* Taml */
{
0x6c6d6154
,
346
,
15
,
0x0020
,
1
,
1
,
1
,
0
,
0
,
0
,
0
},
TRUE
},
{
/* Telu */
{
0x756c6554
,
340
,
15
,
0x0020
,
1
,
1
,
1
,
0
,
0
,
0
,
0
},
TRUE
},
{
/* Thaa */
{
0x61616854
,
170
,
8
,
0x0020
,
1
,
1
,
1
,
0
,
0
,
0
,
0
},
TRUE
},
{
/* Thai */
{
0x69616854
,
352
,
8
,
0x0020
,
1
,
0
,
1
,
0
,
1
,
0
,
0
},
TRUE
},
{
/* Tibt */
{
0x74626954
,
330
,
8
,
0x0020
,
1
,
1
,
1
,
0
,
0
,
0
,
0
},
TRUE
},
{
/* Tfng */
{
0x676e6654
,
120
,
8
,
0x0020
,
1
,
1
,
1
,
0
,
0
,
0
,
0
},
TRUE
},
{
/* Sinh */
{
0x686e6953
,
348
,
8
,
0x0020
,
1
,
1
,
1
,
0
,
0
,
0
,
0
},
_OT
(
's'
,
'i'
,
'n'
,
'h'
),
0
,
TRUE
},
{
/* Sora */
{
0x61726f53
,
398
,
1
,
0x0020
,
0
,
0
,
0
,
0
,
0
,
0
,
0
}
,
_OT
(
's'
,
'o'
,
'r'
,
'a'
)
},
{
/* Sund */
{
0x646e7553
,
362
,
8
,
0x0020
,
1
,
1
,
1
,
0
,
0
,
0
,
0
}
,
_OT
(
's'
,
'u'
,
'n'
,
'd'
)
},
{
/* Sylo */
{
0x6f6c7953
,
316
,
8
,
0x0020
,
1
,
1
,
0
,
0
,
0
,
1
,
0
}
,
_OT
(
's'
,
'y'
,
'l'
,
'o'
)
},
{
/* Syrc */
{
0x63727953
,
135
,
8
,
0x0640
,
0
,
1
,
0
,
0
,
0
,
1
,
1
},
_OT
(
's'
,
'y'
,
'r'
,
'c'
),
0
,
TRUE
},
{
/* Tglg */
{
0x676c6754
,
370
,
8
,
0x0020
,
0
,
1
,
1
,
0
,
0
,
0
,
0
}
,
_OT
(
't'
,
'g'
,
'l'
,
'g'
)
},
{
/* Tagb */
{
0x62676154
,
373
,
8
,
0x0020
,
0
,
1
,
1
,
0
,
0
,
0
,
0
}
,
_OT
(
't'
,
'a'
,
'g'
,
'b'
)
},
{
/* Tale */
{
0x656c6154
,
353
,
1
,
0x0020
,
0
,
1
,
1
,
0
,
0
,
0
,
0
},
_OT
(
't'
,
'a'
,
'l'
,
'e'
),
0
,
TRUE
},
{
/* Lana */
{
0x616e614c
,
351
,
8
,
0x0020
,
1
,
0
,
1
,
0
,
0
,
0
,
0
}
,
_OT
(
'l'
,
'a'
,
'n'
,
'a'
)
},
{
/* Tavt */
{
0x74766154
,
359
,
8
,
0x0020
,
1
,
0
,
1
,
0
,
1
,
0
,
0
}
,
_OT
(
't'
,
'a'
,
'v'
,
't'
)
},
{
/* Takr */
{
0x726b6154
,
321
,
1
,
0x0020
,
0
,
0
,
0
,
0
,
0
,
0
,
0
}
,
_OT
(
't'
,
'a'
,
'k'
,
'r'
)
},
{
/* Taml */
{
0x6c6d6154
,
346
,
15
,
0x0020
,
1
,
1
,
1
,
0
,
0
,
0
,
0
},
_OT
(
't'
,
'a'
,
'm'
,
'l'
),
_OT
(
't'
,
'm'
,
'l'
,
'2'
),
TRUE
},
{
/* Telu */
{
0x756c6554
,
340
,
15
,
0x0020
,
1
,
1
,
1
,
0
,
0
,
0
,
0
},
_OT
(
't'
,
'e'
,
'l'
,
'u'
),
_OT
(
't'
,
'e'
,
'l'
,
'2'
),
TRUE
},
{
/* Thaa */
{
0x61616854
,
170
,
8
,
0x0020
,
1
,
1
,
1
,
0
,
0
,
0
,
0
},
_OT
(
't'
,
'h'
,
'a'
,
'a'
),
0
,
TRUE
},
{
/* Thai */
{
0x69616854
,
352
,
8
,
0x0020
,
1
,
0
,
1
,
0
,
1
,
0
,
0
},
_OT
(
't'
,
'h'
,
'a'
,
'i'
),
0
,
TRUE
},
{
/* Tibt */
{
0x74626954
,
330
,
8
,
0x0020
,
1
,
1
,
1
,
0
,
0
,
0
,
0
},
_OT
(
't'
,
'i'
,
'b'
,
't'
),
0
,
TRUE
},
{
/* Tfng */
{
0x676e6654
,
120
,
8
,
0x0020
,
1
,
1
,
1
,
0
,
0
,
0
,
0
},
_OT
(
't'
,
'f'
,
'n'
,
'g'
),
0
,
TRUE
},
{
/* Tirh */
{
0x68726954
,
326
,
1
,
0x0020
,
0
,
0
,
0
,
0
,
0
,
0
,
0
}
},
{
/* Ugar */
{
0x72616755
,
40
,
1
,
0x0020
,
0
,
0
,
1
,
1
,
0
,
0
,
0
}
},
{
/* Vaii */
{
0x69696156
,
470
,
1
,
0x0020
,
0
,
1
,
1
,
0
,
0
,
0
,
0
},
TRUE
},
{
/* Ugar */
{
0x72616755
,
40
,
1
,
0x0020
,
0
,
0
,
1
,
1
,
0
,
0
,
0
}
,
_OT
(
'u'
,
'g'
,
'a'
,
'r'
)
},
{
/* Vaii */
{
0x69696156
,
470
,
1
,
0x0020
,
0
,
1
,
1
,
0
,
0
,
0
,
0
},
_OT
(
'v'
,
'a'
,
'i'
,
' '
),
0
,
TRUE
},
{
/* Wara */
{
0x61726157
,
262
,
1
,
0x0020
,
0
,
0
,
0
,
0
,
0
,
0
,
0
}
},
{
/* Yiii */
{
0x69696959
,
460
,
1
,
0x0020
,
0
,
0
,
1
,
1
,
0
,
0
,
0
},
TRUE
}
{
/* Yiii */
{
0x69696959
,
460
,
1
,
0x0020
,
0
,
0
,
1
,
1
,
0
,
0
,
0
},
_OT
(
'y'
,
'i'
,
' '
,
' '
),
0
,
TRUE
}
};
#undef _OT
struct
dwrite_numbersubstitution
{
IDWriteNumberSubstitution
IDWriteNumberSubstitution_iface
;
...
...
@@ -835,6 +840,19 @@ done:
return
hr
;
}
static
UINT32
get_opentype_language
(
const
WCHAR
*
locale
)
{
UINT32
language
=
DWRITE_FONT_FEATURE_TAG_DEFAULT
;
if
(
locale
)
{
WCHAR
tag
[
5
];
if
(
GetLocaleInfoEx
(
locale
,
LOCALE_SOPENTYPELANGUAGETAG
,
tag
,
sizeof
(
tag
)
/
sizeof
(
WCHAR
)))
language
=
DWRITE_MAKE_OPENTYPE_TAG
(
tag
[
0
],
tag
[
1
],
tag
[
2
],
tag
[
3
]);
}
return
language
;
}
static
HRESULT
WINAPI
dwritetextanalyzer_GetGlyphs
(
IDWriteTextAnalyzer2
*
iface
,
WCHAR
const
*
text
,
UINT32
length
,
IDWriteFontFace
*
fontface
,
BOOL
is_sideways
,
BOOL
is_rtl
,
DWRITE_SCRIPT_ANALYSIS
const
*
analysis
,
WCHAR
const
*
locale
,
...
...
@@ -934,12 +952,7 @@ static HRESULT WINAPI dwritetextanalyzer_GetGlyphs(IDWriteTextAnalyzer2 *iface,
context
.
length
=
length
;
context
.
is_rtl
=
is_rtl
;
context
.
max_glyph_count
=
max_glyph_count
;
context
.
language_tag
=
DWRITE_MAKE_OPENTYPE_TAG
(
'd'
,
'f'
,
'l'
,
't'
);
if
(
locale
)
{
WCHAR
tag
[
5
];
if
(
GetLocaleInfoEx
(
locale
,
LOCALE_SOPENTYPELANGUAGETAG
,
tag
,
sizeof
(
tag
)
/
sizeof
(
WCHAR
)))
context
.
language_tag
=
DWRITE_MAKE_OPENTYPE_TAG
(
tag
[
0
],
tag
[
1
],
tag
[
2
],
tag
[
3
]);
}
context
.
language_tag
=
get_opentype_language
(
locale
);
scriptprops
=
&
dwritescripts_properties
[
script
];
if
(
scriptprops
->
ops
&&
scriptprops
->
ops
->
contextual_shaping
)
{
...
...
@@ -1165,13 +1178,31 @@ static HRESULT WINAPI dwritetextanalyzer2_GetGlyphOrientationTransform(IDWriteTe
}
static
HRESULT
WINAPI
dwritetextanalyzer2_GetTypographicFeatures
(
IDWriteTextAnalyzer2
*
iface
,
IDWriteFontFace
*
f
ace
,
DWRITE_SCRIPT_ANALYSIS
sa
,
const
WCHAR
*
localeNam
e
,
IDWriteFontFace
*
f
ontface
,
DWRITE_SCRIPT_ANALYSIS
sa
,
const
WCHAR
*
local
e
,
UINT32
max_tagcount
,
UINT32
*
actual_tagcount
,
DWRITE_FONT_FEATURE_TAG
*
tags
)
{
FIXME
(
"(%p %u %s %u %p %p): stub
\n
"
,
face
,
sa
.
script
,
debugstr_w
(
localeName
),
max_tagcount
,
actual_tagcount
,
const
struct
dwritescript_properties
*
props
;
HRESULT
hr
=
S_OK
;
UINT32
language
;
TRACE
(
"(%p %u %s %u %p %p)
\n
"
,
fontface
,
sa
.
script
,
debugstr_w
(
locale
),
max_tagcount
,
actual_tagcount
,
tags
);
return
E_NOTIMPL
;
}
if
(
sa
.
script
>
Script_LastId
)
return
E_INVALIDARG
;
language
=
get_opentype_language
(
locale
);
props
=
&
dwritescripts_properties
[
sa
.
script
];
*
actual_tagcount
=
0
;
if
(
props
->
scriptalttag
)
hr
=
opentype_get_typographic_features
(
fontface
,
props
->
scriptalttag
,
language
,
max_tagcount
,
actual_tagcount
,
tags
);
if
(
*
actual_tagcount
==
0
)
hr
=
opentype_get_typographic_features
(
fontface
,
props
->
scripttag
,
language
,
max_tagcount
,
actual_tagcount
,
tags
);
return
hr
;
};
static
HRESULT
WINAPI
dwritetextanalyzer2_CheckTypographicFeature
(
IDWriteTextAnalyzer2
*
iface
,
IDWriteFontFace
*
face
,
DWRITE_SCRIPT_ANALYSIS
sa
,
const
WCHAR
*
localeName
,
...
...
dlls/dwrite/dwrite_private.h
View file @
6b0623fb
...
...
@@ -130,6 +130,7 @@ extern HRESULT opentype_cmap_get_unicode_ranges(void*,UINT32,DWRITE_UNICODE_RANG
extern
void
opentype_get_font_properties
(
const
void
*
,
const
void
*
,
DWRITE_FONT_STRETCH
*
,
DWRITE_FONT_WEIGHT
*
,
DWRITE_FONT_STYLE
*
)
DECLSPEC_HIDDEN
;
extern
void
opentype_get_font_metrics
(
IDWriteFontFileStream
*
,
DWRITE_FONT_FACE_TYPE
,
UINT32
,
DWRITE_FONT_METRICS1
*
)
DECLSPEC_HIDDEN
;
extern
HRESULT
opentype_get_font_strings_from_id
(
const
void
*
,
DWRITE_INFORMATIONAL_STRING_ID
,
IDWriteLocalizedStrings
**
)
DECLSPEC_HIDDEN
;
extern
HRESULT
opentype_get_typographic_features
(
IDWriteFontFace
*
,
UINT32
,
UINT32
,
UINT32
,
UINT32
*
,
DWRITE_FONT_FEATURE_TAG
*
)
DECLSPEC_HIDDEN
;
/* BiDi helpers */
extern
HRESULT
bidi_computelevels
(
const
WCHAR
*
,
UINT32
,
UINT8
,
UINT8
*
,
UINT8
*
)
DECLSPEC_HIDDEN
;
...
...
dlls/dwrite/opentype.c
View file @
6b0623fb
...
...
@@ -30,6 +30,8 @@ WINE_DEFAULT_DEBUG_CHANNEL(dwrite);
#define MS_OS2_TAG DWRITE_MAKE_OPENTYPE_TAG('O','S','/','2')
#define MS_POST_TAG DWRITE_MAKE_OPENTYPE_TAG('p','o','s','t')
#define MS_TTCF_TAG DWRITE_MAKE_OPENTYPE_TAG('t','t','c','f')
#define MS_GPOS_TAG DWRITE_MAKE_OPENTYPE_TAG('G','P','O','S')
#define MS_GSUB_TAG DWRITE_MAKE_OPENTYPE_TAG('G','S','U','B')
#ifdef WORDS_BIGENDIAN
#define GET_BE_WORD(x) (x)
...
...
@@ -236,6 +238,51 @@ typedef struct {
TT_NameRecord
nameRecord
[
1
];
}
TT_NAME_V0
;
typedef
struct
{
CHAR
FeatureTag
[
4
];
WORD
Feature
;
}
OT_FeatureRecord
;
typedef
struct
{
WORD
FeatureCount
;
OT_FeatureRecord
FeatureRecord
[
1
];
}
OT_FeatureList
;
typedef
struct
{
WORD
LookupOrder
;
/* Reserved */
WORD
ReqFeatureIndex
;
WORD
FeatureCount
;
WORD
FeatureIndex
[
1
];
}
OT_LangSys
;
typedef
struct
{
CHAR
LangSysTag
[
4
];
WORD
LangSys
;
}
OT_LangSysRecord
;
typedef
struct
{
WORD
DefaultLangSys
;
WORD
LangSysCount
;
OT_LangSysRecord
LangSysRecord
[
1
];
}
OT_Script
;
typedef
struct
{
CHAR
ScriptTag
[
4
];
WORD
Script
;
}
OT_ScriptRecord
;
typedef
struct
{
WORD
ScriptCount
;
OT_ScriptRecord
ScriptRecord
[
1
];
}
OT_ScriptList
;
typedef
struct
{
DWORD
version
;
WORD
ScriptList
;
WORD
FeatureList
;
WORD
LookupList
;
}
GPOS_GSUB_Header
;
enum
OPENTYPE_PLATFORM_ID
{
OPENTYPE_PLATFORM_UNICODE
=
0
,
...
...
@@ -1217,3 +1264,87 @@ HRESULT opentype_get_font_strings_from_id(const void *table_data, DWRITE_INFORMA
return
hr
;
}
static
inline
const
OT_Script
*
opentype_get_script
(
const
OT_ScriptList
*
scriptlist
,
UINT32
scripttag
)
{
UINT16
j
;
for
(
j
=
0
;
j
<
GET_BE_WORD
(
scriptlist
->
ScriptCount
);
j
++
)
{
const
char
*
tag
=
scriptlist
->
ScriptRecord
[
j
].
ScriptTag
;
if
(
scripttag
==
DWRITE_MAKE_OPENTYPE_TAG
(
tag
[
0
],
tag
[
1
],
tag
[
2
],
tag
[
3
]))
return
(
OT_Script
*
)((
BYTE
*
)
scriptlist
+
GET_BE_WORD
(
scriptlist
->
ScriptRecord
[
j
].
Script
));
}
return
NULL
;
}
static
inline
const
OT_LangSys
*
opentype_get_langsys
(
const
OT_Script
*
script
,
UINT32
languagetag
)
{
UINT16
j
;
for
(
j
=
0
;
j
<
GET_BE_WORD
(
script
->
LangSysCount
);
j
++
)
{
const
char
*
tag
=
script
->
LangSysRecord
[
j
].
LangSysTag
;
if
(
languagetag
==
DWRITE_MAKE_OPENTYPE_TAG
(
tag
[
0
],
tag
[
1
],
tag
[
2
],
tag
[
3
]))
return
(
OT_LangSys
*
)((
BYTE
*
)
script
+
GET_BE_WORD
(
script
->
LangSysRecord
[
j
].
LangSys
));
}
return
NULL
;
}
static
void
opentype_add_font_features
(
const
GPOS_GSUB_Header
*
header
,
const
OT_LangSys
*
langsys
,
UINT32
max_tagcount
,
UINT32
*
count
,
DWRITE_FONT_FEATURE_TAG
*
tags
)
{
const
OT_FeatureList
*
features
=
(
const
OT_FeatureList
*
)((
const
BYTE
*
)
header
+
GET_BE_WORD
(
header
->
FeatureList
));
UINT16
j
;
for
(
j
=
0
;
j
<
GET_BE_WORD
(
langsys
->
FeatureCount
);
j
++
)
{
const
OT_FeatureRecord
*
feature
=
&
features
->
FeatureRecord
[
langsys
->
FeatureIndex
[
j
]];
const
char
*
tag
=
feature
->
FeatureTag
;
if
(
*
count
<
max_tagcount
)
tags
[
*
count
]
=
DWRITE_MAKE_OPENTYPE_TAG
(
tag
[
0
],
tag
[
1
],
tag
[
2
],
tag
[
3
]);
(
*
count
)
++
;
}
}
HRESULT
opentype_get_typographic_features
(
IDWriteFontFace
*
fontface
,
UINT32
scripttag
,
UINT32
languagetag
,
UINT32
max_tagcount
,
UINT32
*
count
,
DWRITE_FONT_FEATURE_TAG
*
tags
)
{
UINT32
tables
[
2
]
=
{
MS_GSUB_TAG
,
MS_GPOS_TAG
};
HRESULT
hr
;
UINT8
i
;
*
count
=
0
;
for
(
i
=
0
;
i
<
sizeof
(
tables
)
/
sizeof
(
tables
[
0
]);
i
++
)
{
const
OT_ScriptList
*
scriptlist
;
const
GPOS_GSUB_Header
*
header
;
const
OT_Script
*
script
;
const
void
*
ptr
;
void
*
context
;
UINT32
size
;
BOOL
exists
;
exists
=
FALSE
;
hr
=
IDWriteFontFace_TryGetFontTable
(
fontface
,
tables
[
i
],
&
ptr
,
&
size
,
&
context
,
&
exists
);
if
(
FAILED
(
hr
))
return
hr
;
if
(
!
exists
)
continue
;
header
=
(
const
GPOS_GSUB_Header
*
)
ptr
;
scriptlist
=
(
const
OT_ScriptList
*
)((
const
BYTE
*
)
header
+
GET_BE_WORD
(
header
->
ScriptList
));
script
=
opentype_get_script
(
scriptlist
,
scripttag
);
if
(
script
)
{
const
OT_LangSys
*
langsys
=
opentype_get_langsys
(
script
,
languagetag
);
if
(
langsys
)
opentype_add_font_features
(
header
,
langsys
,
max_tagcount
,
count
,
tags
);
}
IDWriteFontFace_ReleaseFontTable
(
fontface
,
context
);
}
return
*
count
>
max_tagcount
?
E_NOT_SUFFICIENT_BUFFER
:
S_OK
;
}
dlls/dwrite/tests/analyzer.c
View file @
6b0623fb
...
...
@@ -1299,8 +1299,8 @@ todo_wine {
memset
(
tags
,
0
,
sizeof
(
tags
));
count
=
0
;
hr
=
IDWriteTextAnalyzer2_GetTypographicFeatures
(
analyzer2
,
fontface
,
sa
,
NULL
,
sizeof
(
tags
)
/
sizeof
(
tags
[
0
]),
&
count
,
tags
);
todo_wine
{
ok
(
hr
==
S_OK
,
"got 0x%08x
\n
"
,
hr
);
todo_wine
{
ok
(
count
>
0
,
"got %u
\n
"
,
count
);
ret
=
has_feature
(
tags
,
count
,
DWRITE_FONT_FEATURE_TAG_CONTEXTUAL_ALTERNATES
);
ok
(
ret
,
"expected 'calt' feature
\n
"
);
...
...
@@ -1311,8 +1311,8 @@ todo_wine {
memset
(
tags
,
0
,
sizeof
(
tags
));
count
=
0
;
hr
=
IDWriteTextAnalyzer2_GetTypographicFeatures
(
analyzer2
,
fontface
,
sa
,
NULL
,
sizeof
(
tags
)
/
sizeof
(
tags
[
0
]),
&
count
,
tags
);
todo_wine
{
ok
(
hr
==
S_OK
,
"got 0x%08x
\n
"
,
hr
);
todo_wine
{
ok
(
count
>
0
,
"got %u
\n
"
,
count
);
ret
=
has_feature
(
tags
,
count
,
DWRITE_FONT_FEATURE_TAG_GLYPH_COMPOSITION_DECOMPOSITION
);
ok
(
ret
,
"expected 'ccmp' feature
\n
"
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment