ReactOS 0.4.17-dev-970-gcf0f1a6
analyzer.c File Reference
#include <assert.h>
#include <stdio.h>
#include <limits.h>
#include <math.h>
#include "initguid.h"
#include "windows.h"
#include "winternl.h"
#include "dwrite_3.h"
#include "usp10.h"
#include "wine/test.h"
Include dependency graph for analyzer.c:

Go to the source code of this file.

Classes

struct  ot_gdef_classdef_format1
 
struct  ot_gdef_class_range
 
struct  ot_gdef_classdef_format2
 
struct  script_analysis
 
struct  call_entry
 
struct  testcontext
 
struct  call_sequence
 
struct  testanalysissource
 
struct  sa_test
 
struct  linebreaks_test
 
struct  textcomplexity_test
 
struct  dwrite_fonttable
 
struct  spacing_test
 
struct  orientation_transf_test
 
struct  bidi_test
 

Macros

#define COBJMACROS
 
#define LRE   0x202a
 
#define RLE   0x202b
 
#define PDF   0x202c
 
#define LRO   0x202d
 
#define RLO   0x202e
 
#define LRI   0x2066
 
#define RLI   0x2067
 
#define FSI   0x2068
 
#define PDI   0x2069
 
#define MS_GDEF_TAG   DWRITE_MAKE_OPENTYPE_TAG('G','D','E','F')
 
#define GET_BE_WORD(x)   RtlUshortByteSwap(x)
 
#define GET_BE_DWORD(x)   RtlUlongByteSwap(x)
 
#define GET_LE_WORD(x)   (x)
 
#define GET_LE_DWORD(x)   (x)
 
#define NUM_CALL_SEQUENCES   1
 
#define ANALYZER_ID   0
 
#define ok_sequence(seq, index, exp, contx, todo)    ok_sequence_(seq, index, (exp), (contx), (todo), __FILE__, __LINE__)
 
#define BREAKPOINT_COUNT   20
 
#define BIDI_LEVELS_COUNT   10
 
#define DELETE_FONTFILE(filename)   _delete_testfontfile(filename, __LINE__)
 
#define P_S   { 0 }
 
#define P_Z   { 0, 0, 0, 1, 0 }
 
#define P_D   { 0, 0, 1, 0, 0 }
 
#define P_D_Z   { 0, 0, 1, 1, 0 }
 

Enumerations

enum  analysis_kind { ScriptAnalysis , LastKind }
 
enum  ot_gdef_class {
  GDEF_CLASS_UNCLASSIFIED = 0 , GDEF_CLASS_BASE = 1 , GDEF_CLASS_LIGATURE = 2 , GDEF_CLASS_MARK = 3 ,
  GDEF_CLASS_COMPONENT = 4 , GDEF_CLASS_MAX = GDEF_CLASS_COMPONENT , GDEF_CLASS_UNCLASSIFIED = 0 , GDEF_CLASS_BASE = 1 ,
  GDEF_CLASS_LIGATURE = 2 , GDEF_CLASS_MARK = 3 , GDEF_CLASS_COMPONENT = 4 , GDEF_CLASS_MAX = GDEF_CLASS_COMPONENT
}
 
enum  script_id { Script_Unknown = 0 , Script_Arabic = 3 , Script_Latin = 49 }
 

Functions

static void * create_text_analyzer (REFIID riid)
 
static const char * get_analysis_kind_name (enum analysis_kind kind)
 
static void add_call (struct call_sequence **seq, int sequence_index, const struct call_entry *call)
 
static void flush_sequence (struct call_sequence **seg, int sequence_index)
 
static void init_call_sequences (struct call_sequence **seq, int n)
 
static void test_uint (UINT32 actual, UINT32 expected, const char *name, const struct testcontext *ctxt)
 
static void ok_sequence_ (struct call_sequence **seq, int sequence_index, const struct call_entry *expected, const char *context, BOOL todo, const char *file, int line)
 
static HRESULT WINAPI analysissink_QueryInterface (IDWriteTextAnalysisSink *iface, REFIID riid, void **obj)
 
static ULONG WINAPI analysissink_AddRef (IDWriteTextAnalysisSink *iface)
 
static ULONG WINAPI analysissink_Release (IDWriteTextAnalysisSink *iface)
 
static HRESULT WINAPI analysissink_SetScriptAnalysis (IDWriteTextAnalysisSink *iface, UINT32 position, UINT32 length, DWRITE_SCRIPT_ANALYSIS const *sa)
 
static HRESULT WINAPI analysissink_SetScriptAnalysis2 (IDWriteTextAnalysisSink *iface, UINT32 position, UINT32 length, DWRITE_SCRIPT_ANALYSIS const *sa)
 
static HRESULT WINAPI analysissink_SetLineBreakpoints (IDWriteTextAnalysisSink *iface, UINT32 position, UINT32 length, DWRITE_LINE_BREAKPOINT const *breakpoints)
 
static HRESULT WINAPI analysissink_SetBidiLevel (IDWriteTextAnalysisSink *iface, UINT32 position, UINT32 length, UINT8 explicitLevel, UINT8 resolvedLevel)
 
static HRESULT WINAPI analysissink_SetNumberSubstitution (IDWriteTextAnalysisSink *iface, UINT32 position, UINT32 length, IDWriteNumberSubstitution *substitution)
 
static HRESULT WINAPI analysissource_QueryInterface (IDWriteTextAnalysisSource *iface, REFIID riid, void **obj)
 
static ULONG WINAPI analysissource_AddRef (IDWriteTextAnalysisSource *iface)
 
static ULONG WINAPI analysissource_Release (IDWriteTextAnalysisSource *iface)
 
static void init_textsource (struct testanalysissource *source, const WCHAR *text, INT text_length, DWRITE_READING_DIRECTION direction)
 
static struct testanalysissource * impl_from_IDWriteTextAnalysisSource (IDWriteTextAnalysisSource *iface)
 
static HRESULT WINAPI analysissource_GetTextAtPosition (IDWriteTextAnalysisSource *iface, UINT32 position, WCHAR const **text, UINT32 *text_len)
 
static HRESULT WINAPI analysissource_GetTextBeforePosition (IDWriteTextAnalysisSource *iface, UINT32 position, WCHAR const **text, UINT32 *text_len)
 
static DWRITE_READING_DIRECTION WINAPI analysissource_GetParagraphReadingDirection (IDWriteTextAnalysisSource *iface)
 
static HRESULT WINAPI analysissource_GetLocaleName (IDWriteTextAnalysisSource *iface, UINT32 position, UINT32 *text_len, WCHAR const **locale)
 
static HRESULT WINAPI analysissource_GetNumberSubstitution (IDWriteTextAnalysisSource *iface, UINT32 position, UINT32 *text_len, IDWriteNumberSubstitution **substitution)
 
static IDWriteFontFace * create_fontface (void)
 
static WCHAR * create_testfontfile (const WCHAR *filename)
 
static void _delete_testfontfile (const WCHAR *filename, int line)
 
static IDWriteFontFace * create_testfontface (const WCHAR *filename)
 
static void init_expected_sa (struct call_sequence **seq, const struct sa_test *test)
 
static void get_script_analysis (const WCHAR *str, DWRITE_SCRIPT_ANALYSIS *sa)
 
static void test_AnalyzeScript (void)
 
static void compare_breakpoints (const struct linebreaks_test *test, DWRITE_LINE_BREAKPOINT *actual)
 
static void test_AnalyzeLineBreakpoints (void)
 
static void test_GetScriptProperties (void)
 
static void test_GetTextComplexity (void)
 
static void test_numbersubstitution (void)
 
static void get_fontface_glyphs (IDWriteFontFace *fontface, const WCHAR *str, UINT16 *glyphs)
 
static void get_fontface_advances (IDWriteFontFace *fontface, FLOAT emsize, const UINT16 *glyphs, FLOAT *advances, UINT32 count)
 
static const void * table_read_ensure (const struct dwrite_fonttable *table, unsigned int offset, unsigned int size)
 
static WORD table_read_be_word (const struct dwrite_fonttable *table, unsigned int offset)
 
static int gdef_class_compare_format2 (const void *g, const void *r)
 
static unsigned int get_glyph_class (const struct dwrite_fonttable *table, UINT16 glyph)
 
static void get_enus_string (IDWriteLocalizedStrings *strings, WCHAR *buff, unsigned int size)
 
static void test_glyph_props (IDWriteTextAnalyzer *analyzer, const WCHAR *family, const WCHAR *face, IDWriteFontFace *fontface)
 
static void test_GetGlyphs (void)
 
static void test_GetTypographicFeatures (void)
 
static void test_GetGlyphPlacements (void)
 
static void test_ApplyCharacterSpacing (void)
 
static const char * dbgstr_matrix (const DWRITE_MATRIX *m)
 
static void test_GetGlyphOrientationTransform (void)
 
static void test_GetBaseline (void)
 
static BOOL float_eq (FLOAT left, FLOAT right)
 
static void test_GetGdiCompatibleGlyphPlacements (void)
 
static void compare_bidi_levels (unsigned int seq, const struct bidi_test *test, UINT32 len, UINT8 *explicit, UINT8 *resolved)
 
static void test_AnalyzeBidi (void)
 
static void test_glyph_justification_property (void)
 
 START_TEST (analyzer)
 

Variables

static IDWriteFactory * factory
 
static struct call_sequence * sequences [NUM_CALL_SEQUENCES]
 
static struct call_sequence * expected_seq [1]
 
static DWRITE_SCRIPT_ANALYSIS g_sa
 
static DWRITE_LINE_BREAKPOINT g_actual_bp [BREAKPOINT_COUNT]
 
static UINT8 g_explicit_levels [BIDI_LEVELS_COUNT]
 
static UINT8 g_resolved_levels [BIDI_LEVELS_COUNT]
 
static IDWriteTextAnalysisSinkVtbl analysissinkvtbl
 
static IDWriteTextAnalysisSinkVtbl analysissinkvtbl2
 
static IDWriteTextAnalysisSink analysissink = { &analysissinkvtbl }
 
static IDWriteTextAnalysisSink analysissink2 = { &analysissinkvtbl2 }
 
static IDWriteTextAnalysisSourceVtbl analysissourcevtbl
 
static struct testanalysissource analysissource = { { &analysissourcevtbl } }
 
static struct sa_test sa_tests []
 
static const struct linebreaks_test linebreaks_tests []
 
static const struct textcomplexity_test textcomplexity_tests []
 
static const struct spacing_test spacing_tests []
 
static const struct orientation_transf_test ot_tests []
 
static const struct bidi_test bidi_tests []
 

Macro Definition Documentation

◆ ANALYZER_ID

#define ANALYZER_ID   0

Definition at line 141 of file analyzer.c.

◆ BIDI_LEVELS_COUNT

#define BIDI_LEVELS_COUNT   10

Definition at line 345 of file analyzer.c.

◆ BREAKPOINT_COUNT

#define BREAKPOINT_COUNT   20

Definition at line 329 of file analyzer.c.

◆ COBJMACROS

#define COBJMACROS

Definition at line 21 of file analyzer.c.

◆ DELETE_FONTFILE

#define DELETE_FONTFILE (   filename)    _delete_testfontfile(filename, __LINE__)

Definition at line 551 of file analyzer.c.

◆ FSI

#define FSI   0x2068

Definition at line 59 of file analyzer.c.

◆ GET_BE_DWORD

#define GET_BE_DWORD (   x)    RtlUlongByteSwap(x)

Definition at line 71 of file analyzer.c.

◆ GET_BE_WORD

#define GET_BE_WORD (   x)    RtlUshortByteSwap(x)

Definition at line 70 of file analyzer.c.

◆ GET_LE_DWORD

#define GET_LE_DWORD (   x)    (x)

Definition at line 73 of file analyzer.c.

◆ GET_LE_WORD

#define GET_LE_WORD (   x)    (x)

Definition at line 72 of file analyzer.c.

◆ LRE

#define LRE   0x202a

Definition at line 52 of file analyzer.c.

◆ LRI

#define LRI   0x2066

Definition at line 57 of file analyzer.c.

◆ LRO

#define LRO   0x202d

Definition at line 55 of file analyzer.c.

◆ MS_GDEF_TAG

#define MS_GDEF_TAG   DWRITE_MAKE_OPENTYPE_TAG('G','D','E','F')

Definition at line 62 of file analyzer.c.

◆ NUM_CALL_SEQUENCES

#define NUM_CALL_SEQUENCES   1

Definition at line 140 of file analyzer.c.

◆ ok_sequence

#define ok_sequence (   seq,
  index,
  exp,
  contx,
  todo 
)     ok_sequence_(seq, index, (exp), (contx), (todo), __FILE__, __LINE__)

Definition at line 284 of file analyzer.c.

◆ P_D

#define P_D   { 0, 0, 1, 0, 0 }

◆ P_D_Z

#define P_D_Z   { 0, 0, 1, 1, 0 }

◆ P_S

#define P_S   { 0 }

◆ P_Z

#define P_Z   { 0, 0, 0, 1, 0 }

◆ PDF

#define PDF   0x202c

Definition at line 54 of file analyzer.c.

◆ PDI

#define PDI   0x2069

Definition at line 60 of file analyzer.c.

◆ RLE

#define RLE   0x202b

Definition at line 53 of file analyzer.c.

◆ RLI

#define RLI   0x2067

Definition at line 58 of file analyzer.c.

◆ RLO

#define RLO   0x202e

Definition at line 56 of file analyzer.c.

Enumeration Type Documentation

◆ analysis_kind

Enumerator
ScriptAnalysis 
LastKind 

Definition at line 98 of file analyzer.c.

98 {
101};
@ LastKind
Definition: analyzer.c:100
@ ScriptAnalysis
Definition: analyzer.c:99

◆ ot_gdef_class

Enumerator
GDEF_CLASS_UNCLASSIFIED 
GDEF_CLASS_BASE 
GDEF_CLASS_LIGATURE 
GDEF_CLASS_MARK 
GDEF_CLASS_COMPONENT 
GDEF_CLASS_MAX 
GDEF_CLASS_UNCLASSIFIED 
GDEF_CLASS_BASE 
GDEF_CLASS_LIGATURE 
GDEF_CLASS_MARK 
GDEF_CLASS_COMPONENT 
GDEF_CLASS_MAX 

Definition at line 1459 of file analyzer.c.

1460{
1462 GDEF_CLASS_BASE = 1,
1464 GDEF_CLASS_MARK = 3,
1467};
@ GDEF_CLASS_UNCLASSIFIED
Definition: analyzer.c:1461
@ GDEF_CLASS_MAX
Definition: analyzer.c:1466
@ GDEF_CLASS_BASE
Definition: analyzer.c:1462
@ GDEF_CLASS_LIGATURE
Definition: analyzer.c:1463
@ GDEF_CLASS_MARK
Definition: analyzer.c:1464
@ GDEF_CLASS_COMPONENT
Definition: analyzer.c:1465

◆ script_id

Enumerator
Script_Unknown 
Script_Arabic 
Script_Latin 

Definition at line 2852 of file analyzer.c.

2853{
2854 Script_Unknown = 0,
2855 Script_Arabic = 3,
2856 Script_Latin = 49,
2857};
@ Script_Arabic
Definition: analyzer.c:2855
@ Script_Latin
Definition: analyzer.c:2856
@ Script_Unknown
Definition: scripts.h:6

Function Documentation

◆ _delete_testfontfile()

static void _delete_testfontfile ( const WCHAR *  filename,
int  line 
)
static

Definition at line 552 of file analyzer.c.

553{
555 ok_(__FILE__,line)(ret, "failed to delete file %s, error %ld\n", wine_dbgstr_w(filename), GetLastError());
556}
#define ok_(x1, x2)
Definition: atltest.h:61
BOOL WINAPI DeleteFileW(IN LPCWSTR lpFileName)
Definition: delete.c:39
return ret
Definition: mutex.c:147
unsigned int BOOL
Definition: ntddk_ex.h:94
const char * filename
Definition: ioapi.h:137
#define wine_dbgstr_w
Definition: kernel32.h:34
Definition: parser.c:49
DWORD WINAPI GetLastError(void)
Definition: except.c:1042

◆ add_call()

static void add_call ( struct call_sequence **  seq,
int  sequence_index,
const struct call_entry *  call 
)
static

Definition at line 145 of file analyzer.c.

146{
147 struct call_sequence *call_seq = seq[sequence_index];
148
149 if (!call_seq->sequence)
150 {
151 call_seq->size = 10;
152 call_seq->sequence = malloc(call_seq->size * sizeof(*call_seq->sequence));
153 }
154
155 if (call_seq->count == call_seq->size)
156 {
157 call_seq->size *= 2;
158 call_seq->sequence = realloc(call_seq->sequence, call_seq->size * sizeof(*call_seq->sequence));
159 }
160
161 assert(call_seq->sequence);
162
163 call_seq->sequence[call_seq->count++] = *call;
164}
#define realloc
Definition: debug_ros.c:6
#define malloc
Definition: debug_ros.c:4
#define assert(_expr)
Definition: assert.h:32
struct call_entry * sequence
Definition: analyzer.c:137

Referenced by analysissink_SetScriptAnalysis(), init_expected_sa(), and ok_sequence_().

◆ analysissink_AddRef()

static ULONG WINAPI analysissink_AddRef ( IDWriteTextAnalysisSink *  iface)
static

Definition at line 299 of file analyzer.c.

300{
301 return 2;
302}

◆ analysissink_QueryInterface()

static HRESULT WINAPI analysissink_QueryInterface ( IDWriteTextAnalysisSink *  iface,
REFIID  riid,
void **  obj 
)
static

Definition at line 287 of file analyzer.c.

288{
289 if (IsEqualIID(riid, &IID_IDWriteTextAnalysisSink) || IsEqualIID(riid, &IID_IUnknown))
290 {
291 *obj = iface;
292 return S_OK;
293 }
294
295 *obj = NULL;
296 return E_NOINTERFACE;
297}
const GUID IID_IUnknown
#define NULL
Definition: types.h:112
REFIID riid
Definition: atlbase.h:39
#define S_OK
Definition: intsafe.h:52
#define IsEqualIID(riid1, riid2)
Definition: guiddef.h:95
#define E_NOINTERFACE
Definition: winerror.h:3479

◆ analysissink_Release()

static ULONG WINAPI analysissink_Release ( IDWriteTextAnalysisSink *  iface)
static

Definition at line 304 of file analyzer.c.

305{
306 return 1;
307}

◆ analysissink_SetBidiLevel()

static HRESULT WINAPI analysissink_SetBidiLevel ( IDWriteTextAnalysisSink *  iface,
UINT32  position,
UINT32  length,
UINT8  explicitLevel,
UINT8  resolvedLevel 
)
static

Definition at line 348 of file analyzer.c.

353{
354 if (position + length > BIDI_LEVELS_COUNT) {
355 ok(0, "SetBidiLevel: reported pos=%u, len=%u overflows expected length %d\n", position, length, BIDI_LEVELS_COUNT);
356 return E_FAIL;
357 }
358 memset(g_explicit_levels + position, explicitLevel, length);
359 memset(g_resolved_levels + position, resolvedLevel, length);
360 return S_OK;
361}
#define ok(value,...)
Definition: atltest.h:57
#define E_FAIL
Definition: ddrawi.h:102
GLuint GLsizei GLsizei * length
Definition: glext.h:6040
#define BIDI_LEVELS_COUNT
Definition: analyzer.c:345
static UINT8 g_resolved_levels[BIDI_LEVELS_COUNT]
Definition: analyzer.c:347
static UINT8 g_explicit_levels[BIDI_LEVELS_COUNT]
Definition: analyzer.c:346
#define memset(x, y, z)
Definition: compat.h:39

◆ analysissink_SetLineBreakpoints()

static HRESULT WINAPI analysissink_SetLineBreakpoints ( IDWriteTextAnalysisSink *  iface,
UINT32  position,
UINT32  length,
DWRITE_LINE_BREAKPOINT const *  breakpoints 
)
static

Definition at line 332 of file analyzer.c.

336{
337 if (position + length > BREAKPOINT_COUNT) {
338 ok(0, "SetLineBreakpoints: reported pos=%u, len=%u overflows expected length %d\n", position, length, BREAKPOINT_COUNT);
339 return E_FAIL;
340 }
341 memcpy(&g_actual_bp[position], breakpoints, length*sizeof(DWRITE_LINE_BREAKPOINT));
342 return S_OK;
343}
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define BREAKPOINT_COUNT
Definition: analyzer.c:329
static DWRITE_LINE_BREAKPOINT g_actual_bp[BREAKPOINT_COUNT]
Definition: analyzer.c:330

◆ analysissink_SetNumberSubstitution()

static HRESULT WINAPI analysissink_SetNumberSubstitution ( IDWriteTextAnalysisSink *  iface,
UINT32  position,
UINT32  length,
IDWriteNumberSubstitution *  substitution 
)
static

Definition at line 363 of file analyzer.c.

367{
368 ok(0, "unexpected\n");
369 return E_NOTIMPL;
370}
#define E_NOTIMPL
Definition: ddrawi.h:99

◆ analysissink_SetScriptAnalysis()

static HRESULT WINAPI analysissink_SetScriptAnalysis ( IDWriteTextAnalysisSink *  iface,
UINT32  position,
UINT32  length,
DWRITE_SCRIPT_ANALYSIS const *  sa 
)
static

Definition at line 309 of file analyzer.c.

311{
312 struct call_entry entry;
313 entry.kind = ScriptAnalysis;
314 entry.sa.pos = position;
315 entry.sa.len = length;
316 entry.sa.shapes = sa->shapes;
318 return S_OK;
319}
static struct sockaddr_in sa
Definition: adnsresfilter.c:69
uint32_t entry
Definition: isohybrid.c:63
static void add_call(struct call_sequence **seq, int sequence_index, const struct call_entry *call)
Definition: analyzer.c:145
#define ANALYZER_ID
Definition: analyzer.c:141
static struct call_sequence * sequences[NUM_CALL_SEQUENCES]
Definition: analyzer.c:142
Definition: analyzer.c:120

◆ analysissink_SetScriptAnalysis2()

static HRESULT WINAPI analysissink_SetScriptAnalysis2 ( IDWriteTextAnalysisSink *  iface,
UINT32  position,
UINT32  length,
DWRITE_SCRIPT_ANALYSIS const *  sa 
)
static

Definition at line 322 of file analyzer.c.

324{
325 g_sa = *sa;
326 return S_OK;
327}
static DWRITE_SCRIPT_ANALYSIS g_sa
Definition: analyzer.c:321

◆ analysissource_AddRef()

static ULONG WINAPI analysissource_AddRef ( IDWriteTextAnalysisSource *  iface)
static

Definition at line 402 of file analyzer.c.

403{
404 ok(0, "AddRef not expected\n");
405 return 2;
406}

◆ analysissource_GetLocaleName()

static HRESULT WINAPI analysissource_GetLocaleName ( IDWriteTextAnalysisSource *  iface,
UINT32  position,
UINT32 *  text_len,
WCHAR const **  locale 
)
static

Definition at line 468 of file analyzer.c.

470{
471 *locale = NULL;
472 *text_len = 0;
473 return S_OK;
474}
Definition: _locale.h:75

◆ analysissource_GetNumberSubstitution()

static HRESULT WINAPI analysissource_GetNumberSubstitution ( IDWriteTextAnalysisSource *  iface,
UINT32  position,
UINT32 *  text_len,
IDWriteNumberSubstitution **  substitution 
)
static

Definition at line 476 of file analyzer.c.

478{
479 ok(0, "unexpected\n");
480 return E_NOTIMPL;
481}

◆ analysissource_GetParagraphReadingDirection()

static DWRITE_READING_DIRECTION WINAPI analysissource_GetParagraphReadingDirection ( IDWriteTextAnalysisSource *  iface)
static

Definition at line 461 of file analyzer.c.

463{
465 return source->direction;
466}
static struct testanalysissource * impl_from_IDWriteTextAnalysisSource(IDWriteTextAnalysisSource *iface)
Definition: analyzer.c:430

◆ analysissource_GetTextAtPosition()

static HRESULT WINAPI analysissource_GetTextAtPosition ( IDWriteTextAnalysisSource *  iface,
UINT32  position,
WCHAR const **  text,
UINT32 *  text_len 
)
static

Definition at line 435 of file analyzer.c.

437{
439
440 if (position >= source->text_length)
441 {
442 *text = NULL;
443 *text_len = 0;
444 }
445 else
446 {
447 *text = source->text + position;
448 *text_len = source->text_length - position;
449 }
450
451 return S_OK;
452}
const WCHAR * text
Definition: package.c:1826

◆ analysissource_GetTextBeforePosition()

static HRESULT WINAPI analysissource_GetTextBeforePosition ( IDWriteTextAnalysisSource *  iface,
UINT32  position,
WCHAR const **  text,
UINT32 *  text_len 
)
static

Definition at line 454 of file analyzer.c.

456{
457 ok(0, "unexpected\n");
458 return E_NOTIMPL;
459}

◆ analysissource_QueryInterface()

static HRESULT WINAPI analysissource_QueryInterface ( IDWriteTextAnalysisSource *  iface,
REFIID  riid,
void **  obj 
)
static

Definition at line 395 of file analyzer.c.

397{
398 ok(0, "QueryInterface not expected\n");
399 return E_NOTIMPL;
400}

◆ analysissource_Release()

static ULONG WINAPI analysissource_Release ( IDWriteTextAnalysisSource *  iface)
static

Definition at line 408 of file analyzer.c.

409{
410 ok(0, "Release not expected\n");
411 return 1;
412}

◆ compare_bidi_levels()

static void compare_bidi_levels ( unsigned int  seq,
const struct bidi_test *  test,
UINT32  len,
UINT8 *  explicit,
UINT8 *  resolved 
)
static

Definition at line 2759 of file analyzer.c.

2760{
2761 unsigned int i, failcount = 0;
2762 BOOL match;
2763
2764 match = !memcmp(explicit, test->explicit, len);
2765 if (!match) {
2766 if (test->todo) {
2767 failcount++;
2768 todo_wine
2769 ok(0, "test %u: %s wrong explicit levels:\n", seq, wine_dbgstr_w(test->text));
2770 }
2771 else
2772 ok(0, "test %u: %s wrong explicit levels:\n", seq, wine_dbgstr_w(test->text));
2773
2774 for (i = 0; i < len; i++) {
2775 if (test->explicit[i] != explicit[i]) {
2776 if (test->todo) {
2777 failcount++;
2778 todo_wine
2779 ok(0, "\tat %u, explicit level %u, expected %u\n", i, explicit[i], test->explicit[i]);
2780 }
2781 else
2782 ok(0, "\tat %u, explicit level %u, expected %u\n", i, explicit[i], test->explicit[i]);
2783 }
2784 }
2785 }
2786
2787 match = !memcmp(resolved, test->resolved, len);
2788 if (!match) {
2789 if (test->todo) {
2790 failcount++;
2791 todo_wine
2792 ok(0, "test %u: %s wrong resolved levels:\n", seq, wine_dbgstr_w(test->text));
2793 }
2794 else
2795 ok(0, "test %u: %s wrong resolved levels:\n", seq, wine_dbgstr_w(test->text));
2796
2797 for (i = 0; i < len; i++) {
2798 if (test->resolved[i] != resolved[i]) {
2799 if (test->todo) {
2800 failcount++;
2801 todo_wine
2802 ok(0, "\tat %u, resolved level %u, expected %u\n", i, resolved[i], test->resolved[i]);
2803 }
2804 else
2805 ok(0, "\tat %u, resolved level %u, expected %u\n", i, resolved[i], test->resolved[i]);
2806 }
2807 }
2808 }
2809
2810 todo_wine_if(test->todo && failcount == 0)
2811 ok(1, "test %u: marked as \"todo_wine\" but succeeds\n", seq);
2812}
_ACRTIMP int __cdecl memcmp(const void *, const void *, size_t)
Definition: string.c:2807
GLdouble n
Definition: glext.h:7729
GLenum GLsizei len
Definition: glext.h:6722
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
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
#define todo_wine_if(is_todo)
Definition: minitest.h:81
#define todo_wine
Definition: minitest.h:80
#define test
Definition: rosglue.h:37
Definition: match.c:28

Referenced by test_AnalyzeBidi().

◆ compare_breakpoints()

static void compare_breakpoints ( const struct linebreaks_test *  test,
DWRITE_LINE_BREAKPOINT *  actual 
)
static

Definition at line 1191 of file analyzer.c.

1192{
1193 static const char *conditions[] = {"N","CB","NB","B"};
1194 const WCHAR *text = test->text;
1195 int cmp = memcmp(test->bp, actual, sizeof(*actual)*BREAKPOINT_COUNT);
1196 ok(!cmp, "%s: got wrong breakpoint data\n", wine_dbgstr_w(test->text));
1197 if (cmp) {
1198 int i = 0;
1199 while (*text) {
1200 ok(!memcmp(&test->bp[i], &actual[i], sizeof(*actual)),
1201 "%s: got [%s, %s] (%s, %s), expected [%s, %s] (%s, %s)\n",
1202 wine_dbgstr_wn(&test->text[i], 1),
1203 conditions[g_actual_bp[i].breakConditionBefore],
1204 conditions[g_actual_bp[i].breakConditionAfter],
1205 g_actual_bp[i].isWhitespace ? "WS" : "0",
1206 g_actual_bp[i].isSoftHyphen ? "SHY" : "0",
1207 conditions[test->bp[i].breakConditionBefore],
1208 conditions[test->bp[i].breakConditionAfter],
1209 test->bp[i].isWhitespace ? "WS" : "0",
1210 test->bp[i].isSoftHyphen ? "SHY" : "0");
1211 if (g_actual_bp[i].isSoftHyphen)
1212 ok(!g_actual_bp[i].isWhitespace, "%s: soft hyphen marked as a whitespace\n",
1213 wine_dbgstr_wn(&test->text[i], 1));
1214 text++;
1215 i++;
1216 }
1217 }
1218}
#define cmp(status, error)
Definition: error.c:118
short WCHAR
Definition: pedump.c:58
#define wine_dbgstr_wn
Definition: testlist.c:2

Referenced by test_AnalyzeLineBreakpoints().

◆ create_fontface()

static IDWriteFontFace * create_fontface ( void  )
static

Definition at line 496 of file analyzer.c.

497{
498 IDWriteGdiInterop *interop;
499 IDWriteFontFace *fontface;
501 LOGFONTW logfont;
502 HRESULT hr;
503
504 hr = IDWriteFactory_GetGdiInterop(factory, &interop);
505 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
506
507 memset(&logfont, 0, sizeof(logfont));
508 logfont.lfHeight = 12;
509 logfont.lfWidth = 12;
510 logfont.lfWeight = FW_NORMAL;
511 logfont.lfItalic = 1;
512 lstrcpyW(logfont.lfFaceName, L"Tahoma");
513
514 hr = IDWriteGdiInterop_CreateFontFromLOGFONT(interop, &logfont, &font);
515 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
516
517 hr = IDWriteFont_CreateFontFace(font, &fontface);
518 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
519
520 IDWriteFont_Release(font);
521 IDWriteGdiInterop_Release(interop);
522
523 return fontface;
524}
HRESULT hr
Definition: delayimp.cpp:582
#define lstrcpyW
Definition: compat.h:749
#define L(x)
Definition: resources.c:13
Definition: mk_font.cpp:20
BYTE lfItalic
Definition: dimm.idl:64
LONG lfHeight
Definition: dimm.idl:59
LONG lfWeight
Definition: dimm.idl:63
WCHAR lfFaceName[LF_FACESIZE]
Definition: dimm.idl:72
LONG lfWidth
Definition: dimm.idl:60
Definition: main.c:439
#define FW_NORMAL
Definition: wingdi.h:373

Referenced by dwritefactory_CreateFontFace(), get_fontface_from_font(), test_ComputeGlyphOrigins(), test_CreateAlphaTexture(), test_CreateBitmapRenderTarget(), test_CreateGlyphRunAnalysis(), test_font_resource(), test_GetAlphaBlendParams(), test_GetBaseline(), test_GetGdiCompatibleGlyphPlacements(), test_GetGlyphImageFormats(), test_GetGlyphRunOutline(), test_GetGlyphs(), test_GetPaletteEntries(), test_GetRecommendedRenderingMode(), test_GetTextComplexity(), test_GetTypographicFeatures(), test_GetVerticalGlyphVariants(), test_glyph_justification_property(), test_HasKerningPairs(), test_HasVerticalGlyphVariants(), test_inmemory_file_loader(), and test_TranslateColorGlyphRun().

◆ create_testfontface()

static IDWriteFontFace * create_testfontface ( const WCHAR *  filename)
static

Definition at line 558 of file analyzer.c.

559{
562 HRESULT hr;
563
564 hr = IDWriteFactory_CreateFontFileReference(factory, filename, NULL, &file);
565 ok(hr == S_OK, "Unexpected hr %#lx.\n",hr);
566
567 hr = IDWriteFactory_CreateFontFace(factory, DWRITE_FONT_FACE_TYPE_TRUETYPE, 1, &file, 0,
569 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
570 IDWriteFontFile_Release(file);
571
572 return face;
573}
WORD face[3]
Definition: mesh.c:4854
@ DWRITE_FONT_FACE_TYPE_TRUETYPE
Definition: dwrite.idl:62
@ DWRITE_FONT_SIMULATIONS_NONE
Definition: dwrite.idl:146
GLenum GLuint GLint GLenum face
Definition: glext.h:7025
Definition: fci.c:123

Referenced by test_GetGlyphPlacements().

◆ create_testfontfile()

static WCHAR * create_testfontfile ( const WCHAR *  filename)
static

Definition at line 526 of file analyzer.c.

527{
528 static WCHAR pathW[MAX_PATH];
529 DWORD written;
530 HANDLE file;
531 HRSRC res;
532 void *ptr;
533
536
538 ok(file != INVALID_HANDLE_VALUE, "file creation failed, at %s, error %ld\n", wine_dbgstr_w(pathW),
539 GetLastError());
540
542 ok(res != 0, "couldn't find resource\n");
545 ok(written == SizeofResource(GetModuleHandleA(NULL), res), "couldn't write resource\n");
547
548 return pathW;
549}
#define ARRAY_SIZE(A)
Definition: main.h:20
#define CloseHandle
Definition: compat.h:739
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
#define GENERIC_READ
Definition: compat.h:135
#define MAX_PATH
Definition: compat.h:34
#define CreateFileW
Definition: compat.h:741
BOOL WINAPI WriteFile(_In_ HANDLE hFile, _In_reads_bytes_opt_(nNumberOfBytesToWrite) LPCVOID lpBuffer, _In_ DWORD nNumberOfBytesToWrite, _Out_opt_ LPDWORD lpNumberOfBytesWritten, _Inout_opt_ LPOVERLAPPED lpOverlapped)
Definition: rw.c:25
HMODULE WINAPI DECLSPEC_HOTPATCH GetModuleHandleA(LPCSTR lpModuleName)
Definition: loader.c:812
DWORD WINAPI GetTempPathW(IN DWORD count, OUT LPWSTR path)
Definition: path.c:2098
HRSRC WINAPI FindResourceA(HMODULE hModule, LPCSTR name, LPCSTR type)
Definition: res.c:155
DWORD WINAPI SizeofResource(HINSTANCE hModule, HRSRC hRsrc)
Definition: res.c:568
LPVOID WINAPI LockResource(HGLOBAL handle)
Definition: res.c:550
HGLOBAL WINAPI LoadResource(HINSTANCE hModule, HRSRC hRsrc)
Definition: res.c:532
unsigned long DWORD
Definition: ntddk_ex.h:95
GLuint res
Definition: glext.h:9613
LPWSTR WINAPI lstrcatW(LPWSTR lpString1, LPCWSTR lpString2)
Definition: lstring.c:274
#define CREATE_ALWAYS
Definition: disk.h:72
static PVOID ptr
Definition: dispmode.c:27
static const WCHAR pathW[]
Definition: path.c:2368
#define GENERIC_WRITE
Definition: nt_native.h:90
#define MAKEINTRESOURCE(i)
Definition: ntverrsrc.c:25
#define RT_RCDATA
Definition: pedump.c:372
const char * LPCSTR
Definition: typedefs.h:52

Referenced by test_GetGlyphPlacements().

◆ create_text_analyzer()

static void * create_text_analyzer ( REFIID  riid)
static

Definition at line 38 of file analyzer.c.

39{
40 IDWriteTextAnalyzer *analyzer;
41 void *ret = NULL;
42
43 if (SUCCEEDED(IDWriteFactory_CreateTextAnalyzer(factory, &analyzer)))
44 {
45 IDWriteTextAnalyzer_QueryInterface(analyzer, riid, &ret);
46 IDWriteTextAnalyzer_Release(analyzer);
47 }
48
49 return ret;
50}
#define SUCCEEDED(hr)
Definition: intsafe.h:50

Referenced by get_script_analysis(), test_AnalyzeBidi(), test_AnalyzeLineBreakpoints(), test_AnalyzeScript(), test_ApplyCharacterSpacing(), test_GetBaseline(), test_GetGdiCompatibleGlyphPlacements(), test_GetGlyphOrientationTransform(), test_GetGlyphPlacements(), test_GetGlyphs(), test_GetScriptProperties(), test_GetTextComplexity(), test_GetTypographicFeatures(), and test_glyph_justification_property().

◆ dbgstr_matrix()

static const char * dbgstr_matrix ( const DWRITE_MATRIX *  m)
inlinestatic

Definition at line 2371 of file analyzer.c.

2372{
2373 static char buff[64];
2374 sprintf(buff, "{%.2f, %.2f, %.2f, %.2f, %.2f, %.2f}", m->m11, m->m12,
2375 m->m21, m->m22, m->dx, m->dy);
2376 return buff;
2377}
const GLfloat * m
Definition: glext.h:10848
#define sprintf
Definition: sprintf.c:45
static const char *static const char const char DWORD void DWORD *static const char const char DWORD void DWORD *static const char DWORD DWORD void * buff
Definition: shcore.c:41

Referenced by test_GetGlyphOrientationTransform().

◆ float_eq()

static BOOL float_eq ( FLOAT  left,
FLOAT  right 
)
inlinestatic

Definition at line 2560 of file analyzer.c.

2561{
2562 int x = *(int *)&left;
2563 int y = *(int *)&right;
2564
2565 if (x < 0)
2566 x = INT_MIN - x;
2567 if (y < 0)
2568 y = INT_MIN - y;
2569
2570 return abs(x - y) <= 8;
2571}
#define INT_MIN
Definition: limits.h:25
#define abs(i)
Definition: fconv.c:206
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
GLint GLint GLint GLint GLint GLint y
Definition: gl.h:1548
GLdouble GLdouble right
Definition: glext.h:10859
GLint left
Definition: glext.h:7726

Referenced by test_GetGdiCompatibleGlyphPlacements().

◆ flush_sequence()

static void flush_sequence ( struct call_sequence **  seg,
int  sequence_index 
)
inlinestatic

Definition at line 166 of file analyzer.c.

167{
168 struct call_sequence *call_seq = seg[sequence_index];
169
170 free(call_seq->sequence);
171 call_seq->sequence = NULL;
172 call_seq->count = call_seq->size = 0;
173}
#define free
Definition: debug_ros.c:5

◆ gdef_class_compare_format2()

static int gdef_class_compare_format2 ( const void *  g,
const void *  r 
)
static

Definition at line 1490 of file analyzer.c.

1491{
1492 const struct ot_gdef_class_range *range = r;
1493 UINT16 glyph = *(UINT16 *)g;
1494
1495 if (glyph < GET_BE_WORD(range->start_glyph))
1496 return -1;
1497 else if (glyph > GET_BE_WORD(range->end_glyph))
1498 return 1;
1499 else
1500 return 0;
1501}
unsigned short UINT16
Definition: actypes.h:129
range
Definition: d3dx9_private.h:58
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
GLboolean GLboolean g
Definition: glext.h:6204
#define GET_BE_WORD(x)
Definition: analyzer.c:70

Referenced by get_glyph_class().

◆ get_analysis_kind_name()

static const char * get_analysis_kind_name ( enum analysis_kind  kind)
static

Definition at line 103 of file analyzer.c.

104{
105 switch (kind)
106 {
107 case ScriptAnalysis:
108 return "ScriptAnalysis";
109 default:
110 return "unknown";
111 }
112}

Referenced by ok_sequence_(), and test_uint().

◆ get_enus_string()

static void get_enus_string ( IDWriteLocalizedStrings *  strings,
WCHAR *  buff,
unsigned int  size 
)
static

Definition at line 1549 of file analyzer.c.

1550{
1551 BOOL exists = FALSE;
1552 unsigned int index;
1553 HRESULT hr;
1554
1555 hr = IDWriteLocalizedStrings_FindLocaleName(strings, L"en-us", &index, &exists);
1556 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1557
1558 /* Not all fonts have an en-us name! */
1559 if (!exists)
1560 index = 0;
1561
1562 hr = IDWriteLocalizedStrings_GetString(strings, index, buff, size);
1563 ok(hr == S_OK, "Failed to get name string, hr %#lx.\n", hr);
1564}
#define index(s, c)
Definition: various.h:29
#define FALSE
Definition: types.h:117
GLsizei const GLchar *const * strings
Definition: glext.h:7622
GLsizeiptr size
Definition: glext.h:5919
GLuint index
Definition: glext.h:6031

Referenced by test_GetGlyphs().

◆ get_fontface_advances()

static void get_fontface_advances ( IDWriteFontFace *  fontface,
FLOAT  emsize,
const UINT16 *  glyphs,
FLOAT *  advances,
UINT32  count 
)
static

Definition at line 1442 of file analyzer.c.

1443{
1444 DWRITE_FONT_METRICS fontmetrics;
1445 UINT32 i;
1446
1447 IDWriteFontFace_GetMetrics(fontface, &fontmetrics);
1448 for (i = 0; i < count; i++) {
1450 HRESULT hr;
1451
1452 hr = IDWriteFontFace_GetDesignGlyphMetrics(fontface, glyphs + i, 1, &metrics, FALSE);
1453 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1454
1455 advances[i] = (FLOAT)metrics.advanceWidth * emsize / (FLOAT)fontmetrics.designUnitsPerEm;
1456 }
1457}
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLsizei GLenum const GLvoid GLuint GLsizei GLfloat * metrics
Definition: glext.h:11745
#define FLOAT
Definition: i386-dis.c:525
UINT16 designUnitsPerEm
Definition: dwrite.idl:353
float FLOAT
Definition: typedefs.h:69
uint32_t UINT32
Definition: typedefs.h:59

Referenced by test_GetGlyphs().

◆ get_fontface_glyphs()

static void get_fontface_glyphs ( IDWriteFontFace *  fontface,
const WCHAR *  str,
UINT16 *  glyphs 
)
static

Definition at line 1430 of file analyzer.c.

1431{
1432 while (*str) {
1433 UINT32 codepoint = *str;
1434 HRESULT hr;
1435
1436 hr = IDWriteFontFace_GetGlyphIndices(fontface, &codepoint, 1, glyphs++);
1437 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1438 str++;
1439 }
1440}
const WCHAR * str

Referenced by test_GetGlyphs().

◆ get_glyph_class()

static unsigned int get_glyph_class ( const struct dwrite_fonttable *  table,
UINT16  glyph 
)
static

Definition at line 1503 of file analyzer.c.

1504{
1505 unsigned int glyph_class = GDEF_CLASS_UNCLASSIFIED, offset;
1506 WORD format, count;
1507
1509
1511
1512 if (format == 1)
1513 {
1514 const struct ot_gdef_classdef_format1 *format1;
1515
1518 if (format1)
1519 {
1521 if (glyph >= start_glyph && (glyph - start_glyph) < count)
1522 {
1523 glyph_class = GET_BE_WORD(format1->classes[glyph - start_glyph]);
1524 if (glyph_class > GDEF_CLASS_MAX)
1525 glyph_class = GDEF_CLASS_UNCLASSIFIED;
1526 }
1527 }
1528 }
1529 else if (format == 2)
1530 {
1531 const struct ot_gdef_classdef_format2 *format2;
1532
1535 if (format2)
1536 {
1537 const struct ot_gdef_class_range *range = bsearch(&glyph, format2->ranges, count,
1539 glyph_class = range && glyph <= GET_BE_WORD(range->end_glyph) ?
1543 }
1544 }
1545
1546 return glyph_class;
1547}
static const GUID * classes[]
Definition: loader.c:49
unsigned short WORD
Definition: ntddk_ex.h:93
GLintptr offset
Definition: glext.h:5920
static WORD table_read_be_word(const struct dwrite_fonttable *table, unsigned int offset)
Definition: analyzer.c:1484
static const void * table_read_ensure(const struct dwrite_fonttable *table, unsigned int offset, unsigned int size)
Definition: analyzer.c:1476
static int gdef_class_compare_format2(const void *g, const void *r)
Definition: analyzer.c:1490
uint16_t glyph_class
Definition: opentype.c:467
struct ot_gdef_class_range ranges[1]
Definition: opentype.c:474
#define bsearch
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255

Referenced by test_glyph_props().

◆ get_script_analysis()

static void get_script_analysis ( const WCHAR *  str,
DWRITE_SCRIPT_ANALYSIS *  sa 
)
static

Definition at line 1085 of file analyzer.c.

1086{
1087 IDWriteTextAnalyzer *analyzer;
1088 HRESULT hr;
1089
1091
1092 analyzer = create_text_analyzer(&IID_IDWriteTextAnalyzer);
1093 ok(!!analyzer, "Failed to create analyzer instance.\n");
1094
1095 hr = IDWriteTextAnalyzer_AnalyzeScript(analyzer, &analysissource.IDWriteTextAnalysisSource_iface, 0,
1097 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1098
1099 *sa = g_sa;
1100
1101 IDWriteTextAnalyzer_Release(analyzer);
1102}
#define lstrlenW
Definition: compat.h:750
@ DWRITE_READING_DIRECTION_LEFT_TO_RIGHT
Definition: dwrite.idl:200
static void * create_text_analyzer(REFIID riid)
Definition: analyzer.c:38
static void init_textsource(struct testanalysissource *source, const WCHAR *text, INT text_length, DWRITE_READING_DIRECTION direction)
Definition: analyzer.c:422
static struct testanalysissource analysissource
Definition: analyzer.c:494
static IDWriteTextAnalysisSink analysissink2
Definition: analyzer.c:393

Referenced by test_GetGlyphPlacements(), test_GetGlyphs(), and test_GetTypographicFeatures().

◆ impl_from_IDWriteTextAnalysisSource()

static struct testanalysissource * impl_from_IDWriteTextAnalysisSource ( IDWriteTextAnalysisSource *  iface)
inlinestatic

Definition at line 430 of file analyzer.c.

431{
432 return CONTAINING_RECORD(iface, struct testanalysissource, IDWriteTextAnalysisSource_iface);
433}
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260

Referenced by analysissource_GetParagraphReadingDirection(), and analysissource_GetTextAtPosition().

◆ init_call_sequences()

static void init_call_sequences ( struct call_sequence **  seq,
int  n 
)
static

Definition at line 175 of file analyzer.c.

176{
177 int i;
178
179 for (i = 0; i < n; i++)
180 seq[i] = calloc(1, sizeof(*seq[i]));
181}
#define calloc
Definition: rosglue.h:14

Referenced by START_TEST().

◆ init_expected_sa()

static void init_expected_sa ( struct call_sequence **  seq,
const struct sa_test *  test 
)
static

Definition at line 1062 of file analyzer.c.

1063{
1064 static const struct call_entry end_of_sequence = { LastKind };
1065 int i;
1066
1068
1069 /* add expected calls */
1070 for (i = 0; i < test->item_count; i++)
1071 {
1072 struct call_entry call;
1073
1074 call.kind = ScriptAnalysis;
1075 call.sa.pos = test->sa[i].pos;
1076 call.sa.len = test->sa[i].len;
1077 call.sa.shapes = test->sa[i].shapes;
1078 add_call(seq, 0, &call);
1079 }
1080
1081 /* and stop marker */
1082 add_call(seq, 0, &end_of_sequence);
1083}
static void flush_sequence(void)
Definition: SystemMenu.c:184
enum analysis_kind kind
Definition: analyzer.c:121

Referenced by test_AnalyzeScript().

◆ init_textsource()

static void init_textsource ( struct testanalysissource *  source,
const WCHAR *  text,
INT  text_length,
DWRITE_READING_DIRECTION  direction 
)
static

Definition at line 422 of file analyzer.c.

424{
425 source->text = text;
426 source->text_length = text_length == -1 ? lstrlenW(text) : text_length;
427 source->direction = direction;
428};
direction
Definition: netio.c:882

Referenced by get_script_analysis(), test_AnalyzeBidi(), test_AnalyzeLineBreakpoints(), and test_AnalyzeScript().

◆ ok_sequence_()

static void ok_sequence_ ( struct call_sequence **  seq,
int  sequence_index,
const struct call_entry *  expected,
const char *  context,
BOOL  todo,
const char *  file,
int  line 
)
static

Definition at line 195 of file analyzer.c.

198{
199 struct call_sequence *call_seq = seq[sequence_index];
200 static const struct call_entry end_of_sequence = { LastKind };
201 const struct call_entry *actual, *sequence;
202 int failcount = 0;
203 struct testcontext ctxt;
204
205 add_call(seq, sequence_index, &end_of_sequence);
206
207 sequence = call_seq->sequence;
208 actual = sequence;
209
210 ctxt.failcount = &failcount;
211 ctxt.todo = todo;
212 ctxt.file = file;
213 ctxt.line = line;
214
215 while (expected->kind != LastKind && actual->kind != LastKind)
216 {
217 if (expected->kind == actual->kind)
218 {
219 ctxt.kind = expected->kind;
220
221 switch (actual->kind)
222 {
223 case ScriptAnalysis:
224 test_uint(actual->sa.pos, expected->sa.pos, "position", &ctxt);
225 test_uint(actual->sa.len, expected->sa.len, "length", &ctxt);
226 test_uint(actual->sa.shapes, expected->sa.shapes, "shapes", &ctxt);
227 break;
228 default:
229 ok(0, "%s: callback not handled, %s\n", context, get_analysis_kind_name(actual->kind));
230 }
231 expected++;
232 actual++;
233 }
234 else if (todo)
235 {
236 failcount++;
238 {
239 ok_(file, line) (0, "%s: call %s was expected, but got call %s instead\n",
241 }
242
243 flush_sequence(seq, sequence_index);
244 return;
245 }
246 else
247 {
248 ok_(file, line) (0, "%s: call %s was expected, but got call %s instead\n",
250 expected++;
251 actual++;
252 }
253 }
254
255 if (todo)
256 {
258 {
259 if (expected->kind != LastKind || actual->kind != LastKind)
260 {
261 failcount++;
262 ok_(file, line) (0, "%s: the call sequence is not complete: expected %s - actual %s\n",
264 }
265 }
266 }
267 else if (expected->kind != LastKind || actual->kind != LastKind)
268 {
269 ok_(file, line) (0, "%s: the call sequence is not complete: expected %s - actual %s\n",
271 }
272
273 if (todo && !failcount) /* succeeded yet marked todo */
274 {
276 {
277 ok_(file, line)(1, "%s: marked \"todo_wine\" but succeeds\n", context);
278 }
279 }
280
281 flush_sequence(seq, sequence_index);
282}
static struct recvd_message * sequence
Definition: SystemMenu.c:63
BOOL todo
Definition: filedlg.c:313
BOOL expected
Definition: store.c:2000
static void test_uint(UINT32 actual, UINT32 expected, const char *name, const struct testcontext *ctxt)
Definition: analyzer.c:183
static const char * get_analysis_kind_name(enum analysis_kind kind)
Definition: analyzer.c:103
struct script_analysis sa
Definition: analyzer.c:122
Definition: http.c:7252
int * failcount
Definition: analyzer.c:128
const char * file
Definition: analyzer.c:129

◆ START_TEST()

START_TEST ( analyzer  )

Definition at line 2961 of file analyzer.c.

2962{
2963 HRESULT hr;
2964
2966 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2967 if (hr != S_OK)
2968 {
2969 win_skip("failed to create factory\n");
2970 return;
2971 }
2972
2975
2990
2991 IDWriteFactory_Release(factory);
2992}
HRESULT WINAPI DWriteCreateFactory(DWRITE_FACTORY_TYPE type, REFIID riid, IUnknown **ret)
Definition: main.c:2110
@ DWRITE_FACTORY_TYPE_ISOLATED
Definition: dwrite.idl:43
#define win_skip
Definition: minitest.h:67
static void test_GetTypographicFeatures(void)
Definition: analyzer.c:1855
static void test_GetGdiCompatibleGlyphPlacements(void)
Definition: analyzer.c:2573
static void test_AnalyzeBidi(void)
Definition: analyzer.c:2814
static void test_AnalyzeLineBreakpoints(void)
Definition: analyzer.c:1220
static void test_ApplyCharacterSpacing(void)
Definition: analyzer.c:2198
static void test_GetGlyphs(void)
Definition: analyzer.c:1662
static void init_call_sequences(struct call_sequence **seq, int n)
Definition: analyzer.c:175
static void test_numbersubstitution(void)
Definition: analyzer.c:1383
static void test_glyph_justification_property(void)
Definition: analyzer.c:2859
static void test_AnalyzeScript(void)
Definition: analyzer.c:1104
static void test_GetGlyphOrientationTransform(void)
Definition: analyzer.c:2379
static void test_GetScriptProperties(void)
Definition: analyzer.c:1262
#define NUM_CALL_SEQUENCES
Definition: analyzer.c:140
static void test_GetGlyphPlacements(void)
Definition: analyzer.c:1907
static struct call_sequence * expected_seq[1]
Definition: analyzer.c:143
static void test_GetTextComplexity(void)
Definition: analyzer.c:1320
static void test_GetBaseline(void)
Definition: analyzer.c:2496

◆ table_read_be_word()

static WORD table_read_be_word ( const struct dwrite_fonttable *  table,
unsigned int  offset 
)
static

Definition at line 1484 of file analyzer.c.

1485{
1486 const WORD *ptr = table_read_ensure(table, offset, sizeof(*ptr));
1487 return ptr ? GET_BE_WORD(*ptr) : 0;
1488}

Referenced by get_glyph_class(), and test_glyph_props().

◆ table_read_ensure()

static const void * table_read_ensure ( const struct dwrite_fonttable *  table,
unsigned int  offset,
unsigned int  size 
)
static

Definition at line 1476 of file analyzer.c.

1477{
1478 if (size > table->size || offset > table->size - size)
1479 return NULL;
1480
1481 return table->data + offset;
1482}
BYTE * data

Referenced by get_glyph_class(), and table_read_be_word().

◆ test_AnalyzeBidi()

static void test_AnalyzeBidi ( void  )
static

Definition at line 2814 of file analyzer.c.

2815{
2816 const struct bidi_test *ptr = bidi_tests;
2817 IDWriteTextAnalyzer *analyzer;
2818 UINT32 i = 0;
2819 HRESULT hr;
2820
2821 analyzer = create_text_analyzer(&IID_IDWriteTextAnalyzer);
2822 ok(!!analyzer, "Failed to create analyzer instance.\n");
2823
2824 while (*ptr->text)
2825 {
2826 UINT32 len;
2827
2828 init_textsource(&analysissource, ptr->text, -1, ptr->direction);
2829
2830 len = lstrlenW(ptr->text);
2831 if (len > BIDI_LEVELS_COUNT) {
2832 ok(0, "test %u: increase BIDI_LEVELS_COUNT to at least %u\n", i, len);
2833 i++;
2834 ptr++;
2835 continue;
2836 }
2837
2840 hr = IDWriteTextAnalyzer_AnalyzeBidi(analyzer, &analysissource.IDWriteTextAnalysisSource_iface, 0,
2841 len, &analysissink);
2842 ok(hr == S_OK, "%u: unexpected hr %#lx.\n", i, hr);
2844
2845 i++;
2846 ptr++;
2847 }
2848
2849 IDWriteTextAnalyzer_Release(analyzer);
2850}
static const struct bidi_test bidi_tests[]
Definition: analyzer.c:2654
static IDWriteTextAnalysisSink analysissink
Definition: analyzer.c:392
static void compare_bidi_levels(unsigned int seq, const struct bidi_test *test, UINT32 len, UINT8 *explicit, UINT8 *resolved)
Definition: analyzer.c:2759

Referenced by START_TEST().

◆ test_AnalyzeLineBreakpoints()

static void test_AnalyzeLineBreakpoints ( void  )
static

Definition at line 1220 of file analyzer.c.

1221{
1222 const struct linebreaks_test *ptr = linebreaks_tests;
1223 IDWriteTextAnalyzer *analyzer;
1224 UINT32 i = 0;
1225 HRESULT hr;
1226
1227 analyzer = create_text_analyzer(&IID_IDWriteTextAnalyzer);
1228 ok(!!analyzer, "Failed to create analyzer instance.\n");
1229
1231 hr = IDWriteTextAnalyzer_AnalyzeLineBreakpoints(analyzer, &analysissource.IDWriteTextAnalysisSource_iface, 0, 0,
1232 &analysissink);
1233 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1234
1235 while (*ptr->text)
1236 {
1237 UINT32 len;
1238
1240
1241 len = lstrlenW(ptr->text);
1242 if (len > BREAKPOINT_COUNT) {
1243 ok(0, "test %u: increase BREAKPOINT_COUNT to at least %u\n", i, len);
1244 i++;
1245 ptr++;
1246 continue;
1247 }
1248
1249 memset(g_actual_bp, 0, sizeof(g_actual_bp));
1250 hr = IDWriteTextAnalyzer_AnalyzeLineBreakpoints(analyzer, &analysissource.IDWriteTextAnalysisSource_iface,
1251 0, len, &analysissink);
1252 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1254
1255 i++;
1256 ptr++;
1257 }
1258
1259 IDWriteTextAnalyzer_Release(analyzer);
1260}
static void compare_breakpoints(const struct linebreaks_test *test, DWRITE_LINE_BREAKPOINT *actual)
Definition: analyzer.c:1191
static const struct linebreaks_test linebreaks_tests[]
Definition: analyzer.c:1138

Referenced by START_TEST().

◆ test_AnalyzeScript()

static void test_AnalyzeScript ( void  )
static

Definition at line 1104 of file analyzer.c.

1105{
1106 IDWriteTextAnalyzer *analyzer;
1107 HRESULT hr;
1108 UINT i;
1109
1110 analyzer = create_text_analyzer(&IID_IDWriteTextAnalyzer);
1111 ok(!!analyzer, "Failed to create analyzer instance.\n");
1112
1113 for (i = 0; i < ARRAY_SIZE(sa_tests); i++)
1114 {
1117
1119
1121 hr = IDWriteTextAnalyzer_AnalyzeScript(analyzer, &analysissource.IDWriteTextAnalysisSource_iface, 0,
1122 sa_tests[i].str_len == -1 ? lstrlenW(sa_tests[i].string) : sa_tests[i].str_len, &analysissink);
1123 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1126
1128 }
1129
1130 IDWriteTextAnalyzer_Release(analyzer);
1131}
unsigned int UINT
Definition: sysinfo.c:13
void __cdecl void __cdecl void __cdecl void __cdecl void __cdecl void winetest_pop_context(void)
void __cdecl void __cdecl void __cdecl void __cdecl void __cdecl winetest_push_context(const char *fmt,...) __WINE_PRINTF_ATTR(1
Definition: test.h:539
static struct sa_test sa_tests[]
Definition: analyzer.c:582
static void init_expected_sa(struct call_sequence **seq, const struct sa_test *test)
Definition: analyzer.c:1062
#define ok_sequence(seq, index, exp, contx, todo)
Definition: analyzer.c:284
#define str_len
Definition: treelist.c:89

Referenced by START_TEST().

◆ test_ApplyCharacterSpacing()

static void test_ApplyCharacterSpacing ( void  )
static

Definition at line 2198 of file analyzer.c.

2199{
2201 IDWriteTextAnalyzer1 *analyzer;
2202 UINT16 clustermap[2];
2203 HRESULT hr;
2204 int i;
2205
2206 analyzer = create_text_analyzer(&IID_IDWriteTextAnalyzer1);
2207 if (!analyzer)
2208 {
2209 win_skip("ApplyCharacterSpacing() is not supported.\n");
2210 return;
2211 }
2212
2213 for (i = 0; i < ARRAY_SIZE(spacing_tests); ++i)
2214 {
2215 const struct spacing_test *ptr = spacing_tests + i;
2217 UINT32 glyph_count;
2218 FLOAT advances[3];
2219
2220 offsets[0].advanceOffset = ptr->offsets[0];
2221 offsets[1].advanceOffset = ptr->offsets[1];
2222 offsets[2].advanceOffset = ptr->offsets[2];
2223 /* Ascender offsets are never touched as spacing applies in reading direction only,
2224 we'll only test them to see if they are not changed */
2225 offsets[0].ascenderOffset = 23.0;
2226 offsets[1].ascenderOffset = 32.0;
2227 offsets[2].ascenderOffset = 31.0;
2228
2229 advances[0] = advances[1] = 123.45f;
2230 memcpy(props, ptr->props, sizeof(props));
2231 glyph_count = ptr->advances[2] > 0.0 ? 3 : 2;
2232 if (ptr->single_cluster)
2233 {
2234 clustermap[0] = 0;
2235 clustermap[1] = 0;
2236 props[0].isClusterStart = 1;
2237 }
2238 else
2239 {
2240 /* trivial case with one glyph per cluster */
2241 clustermap[0] = 0;
2242 clustermap[1] = 1;
2243 props[0].isClusterStart = props[1].isClusterStart = 1;
2244 }
2245
2246 winetest_push_context("Test %u", i);
2247
2248 hr = IDWriteTextAnalyzer1_ApplyCharacterSpacing(analyzer,
2249 ptr->leading,
2250 ptr->trailing,
2251 ptr->min_advance,
2252 ARRAY_SIZE(clustermap),
2253 glyph_count,
2254 clustermap,
2255 ptr->advances,
2256 offsets,
2257 props,
2258 advances,
2259 offsets);
2260 ok(hr == (ptr->min_advance < 0.0f ? E_INVALIDARG : S_OK), "Unexpected hr %#lx.\n", hr);
2261
2262 if (hr == S_OK) {
2263 ok(ptr->modified_advances[0] == advances[0], "Got advance[0] %.2f, expected %.2f.\n", advances[0], ptr->modified_advances[0]);
2264 ok(ptr->modified_advances[1] == advances[1], "Got advance[1] %.2f, expected %.2f.\n", advances[1], ptr->modified_advances[1]);
2265 if (glyph_count > 2)
2266 ok(ptr->modified_advances[2] == advances[2], "Got advance[2] %.2f, expected %.2f.\n", advances[2], ptr->modified_advances[2]);
2267
2268 ok(ptr->modified_offsets[0] == offsets[0].advanceOffset, "Got offset[0] %.2f, expected %.2f.\n",
2269 offsets[0].advanceOffset, ptr->modified_offsets[0]);
2270 ok(ptr->modified_offsets[1] == offsets[1].advanceOffset, "Got offset[1] %.2f, expected %.2f.\n",
2271 offsets[1].advanceOffset, ptr->modified_offsets[1]);
2272 if (glyph_count > 2)
2273 ok(ptr->modified_offsets[2] == offsets[2].advanceOffset, "Got offset[2] %.2f, expected %.2f.\n",
2274 offsets[2].advanceOffset, ptr->modified_offsets[2]);
2275
2276 ok(offsets[0].ascenderOffset == 23.0, "Unexpected ascenderOffset %.2f.\n", offsets[0].ascenderOffset);
2277 ok(offsets[1].ascenderOffset == 32.0, "Unexpected ascenderOffset %.2f.\n", offsets[1].ascenderOffset);
2278 ok(offsets[2].ascenderOffset == 31.0, "Unexpected ascenderOffset %.2f.\n", offsets[2].ascenderOffset);
2279 }
2280 else {
2281 ok(ptr->modified_advances[0] == advances[0], "Got advance[0] %.2f, expected %.2f.\n", advances[0], ptr->modified_advances[0]);
2282 ok(ptr->modified_advances[1] == advances[1], "Got advance[1] %.2f, expected %.2f.\n", advances[1], ptr->modified_advances[1]);
2283 ok(ptr->offsets[0] == offsets[0].advanceOffset, "Got offset[0] %.2f, expected %.2f.\n",
2284 offsets[0].advanceOffset, ptr->modified_offsets[0]);
2285 ok(ptr->offsets[1] == offsets[1].advanceOffset, "Got offset[1] %.2f, expected %.2f.\n",
2286 offsets[1].advanceOffset, ptr->modified_offsets[1]);
2287 ok(offsets[0].ascenderOffset == 23.0, "Unexpected ascenderOffset %.2f.\n", offsets[0].ascenderOffset);
2288 ok(offsets[1].ascenderOffset == 32.0, "Unexpected ascenderOffset %.2f.\n", offsets[1].ascenderOffset);
2289 }
2290
2291 /* same, with argument aliasing */
2292 memcpy(advances, ptr->advances, glyph_count * sizeof(*advances));
2293 offsets[0].advanceOffset = ptr->offsets[0];
2294 offsets[1].advanceOffset = ptr->offsets[1];
2295 offsets[2].advanceOffset = ptr->offsets[2];
2296 /* Ascender offsets are never touched as spacing applies in reading direction only,
2297 we'll only test them to see if they are not changed */
2298 offsets[0].ascenderOffset = 23.0f;
2299 offsets[1].ascenderOffset = 32.0f;
2300 offsets[2].ascenderOffset = 31.0f;
2301
2302 hr = IDWriteTextAnalyzer1_ApplyCharacterSpacing(analyzer,
2303 ptr->leading,
2304 ptr->trailing,
2305 ptr->min_advance,
2306 ARRAY_SIZE(clustermap),
2307 glyph_count,
2308 clustermap,
2309 advances,
2310 offsets,
2311 props,
2312 advances,
2313 offsets);
2314 ok(hr == (ptr->min_advance < 0.0f ? E_INVALIDARG : S_OK), "Unexpected hr %#lx.\n", hr);
2315
2316 if (hr == S_OK)
2317 {
2318 ok(ptr->modified_advances[0] == advances[0], "Got advance[0] %.2f, expected %.2f.\n", advances[0], ptr->modified_advances[0]);
2319 ok(ptr->modified_advances[1] == advances[1], "Got advance[1] %.2f, expected %.2f.\n", advances[1], ptr->modified_advances[1]);
2320 if (glyph_count > 2)
2321 ok(ptr->modified_advances[2] == advances[2], "Got advance[2] %.2f, expected %.2f.\n", advances[2], ptr->modified_advances[2]);
2322
2323 ok(ptr->modified_offsets[0] == offsets[0].advanceOffset, "Got offset[0] %.2f, expected %.2f.\n",
2324 offsets[0].advanceOffset, ptr->modified_offsets[0]);
2325 ok(ptr->modified_offsets[1] == offsets[1].advanceOffset, "Got offset[1] %.2f, expected %.2f.\n",
2326 offsets[1].advanceOffset, ptr->modified_offsets[1]);
2327 if (glyph_count > 2)
2328 ok(ptr->modified_offsets[2] == offsets[2].advanceOffset, "Got offset[2] %.2f, expected %.2f.\n",
2329 offsets[2].advanceOffset, ptr->modified_offsets[2]);
2330
2331 ok(offsets[0].ascenderOffset == 23.0f, "Unexpected ascenderOffset %.2f.\n", offsets[0].ascenderOffset);
2332 ok(offsets[1].ascenderOffset == 32.0f, "Unexpected ascenderOffset %.2f.\n", offsets[1].ascenderOffset);
2333 ok(offsets[2].ascenderOffset == 31.0f, "Unexpected ascenderOffset %.2f.\n", offsets[2].ascenderOffset);
2334 }
2335 else
2336 {
2337 /* with aliased advances original values are retained */
2338 ok(ptr->advances[0] == advances[0], "Got advance[0] %.2f, expected %.2f.\n", advances[0], ptr->advances[0]);
2339 ok(ptr->advances[1] == advances[1], "Got advance[1] %.2f, expected %.2f.\n", advances[1], ptr->advances[1]);
2340 ok(ptr->offsets[0] == offsets[0].advanceOffset, "Got offset[0] %.2f, expected %.2f.\n",
2341 offsets[0].advanceOffset, ptr->modified_offsets[0]);
2342 ok(ptr->offsets[1] == offsets[1].advanceOffset, "Got offset[1] %.2f, expected %.2f.\n",
2343 offsets[1].advanceOffset, ptr->modified_offsets[1]);
2344 ok(offsets[0].ascenderOffset == 23.0f, "Unexpected ascenderOffset %.2f.\n", offsets[0].ascenderOffset);
2345 ok(offsets[1].ascenderOffset == 32.0f, "Unexpected ascenderOffset %.2f.\n", offsets[1].ascenderOffset);
2346 }
2347
2349 }
2350
2351 IDWriteTextAnalyzer1_Release(analyzer);
2352}
#define E_INVALIDARG
Definition: ddrawi.h:101
static const FxOffsetAndName offsets[]
static const struct spacing_test spacing_tests[]
Definition: analyzer.c:2054
FLOAT advances[3]
Definition: analyzer.c:2046
static const WCHAR props[]
Definition: wbemdisp.c:288

Referenced by START_TEST().

◆ test_GetBaseline()

static void test_GetBaseline ( void  )
static

Definition at line 2496 of file analyzer.c.

2497{
2498 DWRITE_SCRIPT_ANALYSIS sa = { 0 };
2499 IDWriteTextAnalyzer1 *analyzer;
2500 IDWriteFontFace *fontface;
2502 BOOL exists;
2503 HRESULT hr;
2504
2505 analyzer = create_text_analyzer(&IID_IDWriteTextAnalyzer1);
2506 if (!analyzer)
2507 {
2508 win_skip("GetBaseline() is not supported.\n");
2509 return;
2510 }
2511
2512 fontface = create_fontface();
2513
2514 /* Tahoma does not have a BASE table. */
2515
2516 exists = TRUE;
2517 baseline = 456;
2518 hr = IDWriteTextAnalyzer1_GetBaseline(analyzer, fontface, DWRITE_BASELINE_DEFAULT, FALSE,
2519 TRUE, sa, NULL, &baseline, &exists);
2520 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2521 ok(!baseline, "Unexpected baseline %d.\n", baseline);
2522 ok(!exists, "Unexpected flag %d.\n", exists);
2523
2524 exists = TRUE;
2525 baseline = 456;
2526 hr = IDWriteTextAnalyzer1_GetBaseline(analyzer, fontface, DWRITE_BASELINE_DEFAULT, FALSE,
2527 FALSE, sa, NULL, &baseline, &exists);
2528 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2529 ok(!baseline, "Unexpected baseline %d.\n", baseline);
2530 ok(!exists, "Unexpected flag %d.\n", exists);
2531
2532 exists = TRUE;
2533 baseline = 0;
2534 hr = IDWriteTextAnalyzer1_GetBaseline(analyzer, fontface, DWRITE_BASELINE_CENTRAL, FALSE,
2535 TRUE, sa, NULL, &baseline, &exists);
2536 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2537 ok(baseline != 0, "Unexpected baseline %d.\n", baseline);
2538 ok(!exists, "Unexpected flag %d.\n", exists);
2539
2540 exists = TRUE;
2541 baseline = 0;
2542 hr = IDWriteTextAnalyzer1_GetBaseline(analyzer, fontface, DWRITE_BASELINE_CENTRAL, FALSE,
2543 FALSE, sa, NULL, &baseline, &exists);
2544 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2545 ok(!baseline, "Unexpected baseline %d.\n", baseline);
2546 ok(!exists, "Unexpected flag %d.\n", exists);
2547
2548 exists = TRUE;
2549 baseline = 456;
2550 hr = IDWriteTextAnalyzer1_GetBaseline(analyzer, fontface, DWRITE_BASELINE_DEFAULT + 100, FALSE,
2551 TRUE, sa, NULL, &baseline, &exists);
2552 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
2553 ok(!baseline, "Unexpected baseline %d.\n", baseline);
2554 ok(!exists, "Unexpected flag %d.\n", exists);
2555
2556 IDWriteFontFace_Release(fontface);
2557 IDWriteTextAnalyzer1_Release(analyzer);
2558}
#define TRUE
Definition: types.h:120
@ DWRITE_BASELINE_DEFAULT
Definition: dwrite_1.idl:414
@ DWRITE_BASELINE_CENTRAL
Definition: dwrite_1.idl:416
FLOAT baseline
Definition: dwrite_3.idl:860
static IDWriteFontFace * create_fontface(void)
Definition: analyzer.c:496
int32_t INT32
Definition: typedefs.h:58

Referenced by START_TEST().

◆ test_GetGdiCompatibleGlyphPlacements()

static void test_GetGdiCompatibleGlyphPlacements ( void  )
static

Definition at line 2573 of file analyzer.c.

2574{
2575 DWRITE_SHAPING_GLYPH_PROPERTIES glyphprops[1];
2576 DWRITE_SHAPING_TEXT_PROPERTIES textprops[1];
2577 DWRITE_SCRIPT_ANALYSIS sa = { 0 };
2578 IDWriteTextAnalyzer *analyzer;
2579 IDWriteFontFace *fontface;
2580 UINT16 clustermap[1];
2581 HRESULT hr;
2582 UINT32 count;
2583 UINT16 glyphs[1];
2584 FLOAT advance;
2586 DWRITE_FONT_METRICS fontmetrics;
2587 float emsize;
2588
2589 analyzer = create_text_analyzer(&IID_IDWriteTextAnalyzer);
2590 ok(!!analyzer, "Failed to create analyzer instance.\n");
2591
2592 fontface = create_fontface();
2593
2594 IDWriteFontFace_GetMetrics(fontface, &fontmetrics);
2595
2596 count = 0;
2597 hr = IDWriteTextAnalyzer_GetGlyphs(analyzer, L"A", 1, fontface, FALSE, FALSE, &sa, NULL, NULL, NULL, NULL, 0, 1,
2598 clustermap, textprops, glyphs, glyphprops, &count);
2599 ok(hr == S_OK, "Failed to get glyphs, hr %#lx.\n", hr);
2600 ok(count == 1, "got %u\n", count);
2601
2602 for (emsize = 12.0f; emsize <= 20.0f; emsize += 1.0f)
2603 {
2604 FLOAT compatadvance, expected, ppdip;
2606
2607 hr = IDWriteTextAnalyzer_GetGlyphPlacements(analyzer, L"A", clustermap, textprops, 1, glyphs, glyphprops,
2608 count, fontface, emsize, FALSE, FALSE, &sa, NULL, NULL, NULL, 0, &advance, offsets);
2609 ok(hr == S_OK, "Failed to get glyph placements, hr %#lx.\n", hr);
2610 ok(advance > 0.0f, "Unexpected advance %f.\n", advance);
2611
2612 /* 1 ppdip, no transform */
2613 ppdip = 1.0;
2614 hr = IDWriteFontFace_GetGdiCompatibleGlyphMetrics(fontface, emsize, ppdip, NULL, FALSE,
2615 glyphs, 1, &metrics, FALSE);
2616 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2617
2618 expected = floorf(metrics.advanceWidth * emsize * ppdip / fontmetrics.designUnitsPerEm + 0.5f) / ppdip;
2619 hr = IDWriteTextAnalyzer_GetGdiCompatibleGlyphPlacements(analyzer, L"A", clustermap, textprops, 1, glyphs,
2620 glyphprops, count, fontface, emsize, ppdip, NULL, FALSE, FALSE, FALSE, &sa, NULL, NULL, NULL, 0,
2621 &compatadvance, offsets);
2622 ok(hr == S_OK, "Failed to get glyph placements, hr %#lx.\n", hr);
2623 ok(compatadvance == expected, "%.0f: got advance %f, expected %f, natural %f\n", emsize,
2624 compatadvance, expected, advance);
2625
2626 /* 1.2 ppdip, no transform */
2627 ppdip = 1.2f;
2628 hr = IDWriteFontFace_GetGdiCompatibleGlyphMetrics(fontface, emsize, ppdip, NULL, FALSE,
2629 glyphs, 1, &metrics, FALSE);
2630 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2631
2632 expected = floorf(metrics.advanceWidth * emsize * ppdip / fontmetrics.designUnitsPerEm + 0.5f) / ppdip;
2633 hr = IDWriteTextAnalyzer_GetGdiCompatibleGlyphPlacements(analyzer, L"A", clustermap, textprops, 1, glyphs,
2634 glyphprops, count, fontface, emsize, ppdip, NULL, FALSE, FALSE, FALSE, &sa, NULL, NULL, NULL, 0,
2635 &compatadvance, offsets);
2636 ok(hr == S_OK, "Failed to get glyph placements, hr %#lx.\n", hr);
2637 ok(float_eq(compatadvance, expected), "%.0f: got advance %f, expected %f, natural %f\n", emsize,
2638 compatadvance, expected, advance);
2639 }
2640
2641 IDWriteFontFace_Release(fontface);
2642 IDWriteTextAnalyzer_Release(analyzer);
2643}
_STLP_MOVE_TO_STD_NAMESPACE void _STLP_CALL advance(_InputIterator &__i, _Distance __n)
static BOOL float_eq(FLOAT left, FLOAT right)
Definition: analyzer.c:2560
#define floorf(x)
Definition: mymath.h:65

Referenced by START_TEST().

◆ test_GetGlyphOrientationTransform()

static void test_GetGlyphOrientationTransform ( void  )
static

Definition at line 2379 of file analyzer.c.

2380{
2381 IDWriteTextAnalyzer2 *analyzer2;
2382 IDWriteTextAnalyzer1 *analyzer;
2383 FLOAT originx, originy;
2385 HRESULT hr;
2386 int i;
2387
2388 analyzer = create_text_analyzer(&IID_IDWriteTextAnalyzer1);
2389 if (!analyzer)
2390 {
2391 win_skip("GetGlyphOrientationTransform() is not supported.\n");
2392 return;
2393 }
2394
2395 /* invalid angle value */
2396 memset(&m, 0xcc, sizeof(m));
2397 hr = IDWriteTextAnalyzer1_GetGlyphOrientationTransform(analyzer,
2399 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
2400 ok(m.m11 == 0.0, "got %.2f\n", m.m11);
2401
2402 for (i = 0; i < ARRAY_SIZE(ot_tests); ++i)
2403 {
2404 memset(&m, 0, sizeof(m));
2405 hr = IDWriteTextAnalyzer1_GetGlyphOrientationTransform(analyzer, ot_tests[i].angle,
2406 ot_tests[i].is_sideways, &m);
2407 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2408 ok(!memcmp(&ot_tests[i].m, &m, sizeof(m)), "%d: wrong matrix %s\n", i, dbgstr_matrix(&m));
2409 }
2410
2411 IDWriteTextAnalyzer1_Release(analyzer);
2412
2413 analyzer2 = create_text_analyzer(&IID_IDWriteTextAnalyzer2);
2414 if (!analyzer2)
2415 {
2416 win_skip("IDWriteTextAnalyzer2::GetGlyphOrientationTransform() is not supported.\n");
2417 return;
2418 }
2419
2420 /* invalid angle value */
2421 memset(&m, 0xcc, sizeof(m));
2422 hr = IDWriteTextAnalyzer2_GetGlyphOrientationTransform(analyzer2,
2424 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
2425 ok(m.m11 == 0.0, "got %.2f\n", m.m11);
2426
2427 originx = 50.0;
2428 originy = 60.0;
2429 for (i = 0; i < ARRAY_SIZE(ot_tests); i++) {
2431 DWRITE_MATRIX m_exp;
2432
2433 memset(&m, 0, sizeof(m));
2434
2435 /* zero offset gives same result as a call from IDWriteTextAnalyzer1 */
2436 hr = IDWriteTextAnalyzer2_GetGlyphOrientationTransform(analyzer2, ot_tests[i].angle,
2437 ot_tests[i].is_sideways, 0.0, 0.0, &m);
2438 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2439 ok(!memcmp(&ot_tests[i].m, &m, sizeof(m)), "%d: wrong matrix %s\n", i, dbgstr_matrix(&m));
2440
2441 m_exp = ot_tests[i].m;
2442 hr = IDWriteTextAnalyzer2_GetGlyphOrientationTransform(analyzer2, ot_tests[i].angle,
2443 ot_tests[i].is_sideways, originx, originy, &m);
2444 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2445
2446 /* 90 degrees more for sideways */
2447 if (ot_tests[i].is_sideways) {
2448 switch (ot_tests[i].angle)
2449 {
2452 break;
2455 break;
2458 break;
2461 break;
2462 default:
2463 ;
2464 }
2465 }
2466 else
2467 angle = ot_tests[i].angle;
2468
2469 /* set expected offsets */
2470 switch (angle)
2471 {
2473 break;
2475 m_exp.dx = originx + originy;
2476 m_exp.dy = originy - originx;
2477 break;
2479 m_exp.dx = originx + originx;
2480 m_exp.dy = originy + originy;
2481 break;
2483 m_exp.dx = originx - originy;
2484 m_exp.dy = originy + originx;
2485 break;
2486 default:
2487 ;
2488 }
2489
2490 ok(!memcmp(&m_exp, &m, sizeof(m)), "%d: wrong matrix %s\n", i, dbgstr_matrix(&m));
2491 }
2492
2493 IDWriteTextAnalyzer2_Release(analyzer2);
2494}
DWRITE_GLYPH_ORIENTATION_ANGLE
Definition: dwrite_1.idl:432
@ DWRITE_GLYPH_ORIENTATION_ANGLE_180_DEGREES
Definition: dwrite_1.idl:435
@ DWRITE_GLYPH_ORIENTATION_ANGLE_90_DEGREES
Definition: dwrite_1.idl:434
@ DWRITE_GLYPH_ORIENTATION_ANGLE_0_DEGREES
Definition: dwrite_1.idl:433
@ DWRITE_GLYPH_ORIENTATION_ANGLE_270_DEGREES
Definition: dwrite_1.idl:436
GLfloat angle
Definition: glext.h:10853
static const struct orientation_transf_test ot_tests[]
Definition: analyzer.c:2360
static const char * dbgstr_matrix(const DWRITE_MATRIX *m)
Definition: analyzer.c:2371

Referenced by START_TEST().

◆ test_GetGlyphPlacements()

static void test_GetGlyphPlacements ( void  )
static

Definition at line 1907 of file analyzer.c.

1908{
1909 DWRITE_SHAPING_GLYPH_PROPERTIES glyphprops[2];
1910 DWRITE_SHAPING_TEXT_PROPERTIES textprops[2];
1911 static const WCHAR aW[] = {'A','D',0};
1912 UINT16 clustermap[2], glyphs[2];
1914 IDWriteTextAnalyzer *analyzer;
1915 IDWriteFontFace *fontface;
1917 FLOAT advances[2];
1918 UINT32 count, len;
1919 WCHAR *path;
1920 HRESULT hr;
1921
1922 analyzer = create_text_analyzer(&IID_IDWriteTextAnalyzer);
1923 ok(!!analyzer, "Failed to create analyzer instance.\n");
1924
1925 path = create_testfontfile(L"wine_test_font.ttf");
1926 fontface = create_testfontface(path);
1927
1929 count = 0;
1930 len = lstrlenW(aW);
1931 hr = IDWriteTextAnalyzer_GetGlyphs(analyzer, aW, len, fontface, FALSE, FALSE, &sa, NULL,
1932 NULL, NULL, NULL, 0, len, clustermap, textprops, glyphs, glyphprops, &count);
1933 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1934 ok(count == 2, "got %u\n", count);
1935
1936 /* just return on zero glyphs */
1937 advances[0] = advances[1] = 1.0;
1938 offsets[0].advanceOffset = offsets[0].ascenderOffset = 2.0;
1939 hr = IDWriteTextAnalyzer_GetGlyphPlacements(analyzer, aW, clustermap, textprops,
1940 len, glyphs, glyphprops, 0, fontface, 0.0, FALSE, FALSE, &sa, NULL, NULL,
1941 NULL, 0, advances, offsets);
1942 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1943 ok(advances[0] == 1.0, "got %.2f\n", advances[0]);
1944 ok(offsets[0].advanceOffset == 2.0 && offsets[0].ascenderOffset == 2.0, "got %.2f,%.2f\n",
1945 offsets[0].advanceOffset, offsets[0].ascenderOffset);
1946
1947 /* advances/offsets are scaled with provided font emSize and designed eM box size */
1948 advances[0] = advances[1] = 1.0;
1949 memset(offsets, 0xcc, sizeof(offsets));
1950 hr = IDWriteTextAnalyzer_GetGlyphPlacements(analyzer, aW, clustermap, textprops,
1951 len, glyphs, glyphprops, len, fontface, 0.0, FALSE, FALSE, &sa, NULL, NULL,
1952 NULL, 0, advances, offsets);
1953 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1954 ok(advances[0] == 0.0, "got %.2f\n", advances[0]);
1955 ok(offsets[0].advanceOffset == 0.0 && offsets[0].ascenderOffset == 0.0, "got %.2f,%.2f\n",
1956 offsets[0].advanceOffset, offsets[0].ascenderOffset);
1957
1958 advances[0] = advances[1] = 1.0;
1959 memset(offsets, 0xcc, sizeof(offsets));
1960 hr = IDWriteTextAnalyzer_GetGlyphPlacements(analyzer, aW, clustermap, textprops,
1961 len, glyphs, glyphprops, len, fontface, 2048.0, FALSE, FALSE, &sa, NULL, NULL,
1962 NULL, 0, advances, offsets);
1963 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1964 ok(advances[0] == 1000.0, "got %.2f\n", advances[0]);
1965 ok(offsets[0].advanceOffset == 0.0 && offsets[0].ascenderOffset == 0.0, "got %.2f,%.2f\n",
1966 offsets[0].advanceOffset, offsets[0].ascenderOffset);
1967
1968 advances[0] = advances[1] = 1.0;
1969 memset(offsets, 0xcc, sizeof(offsets));
1970 hr = IDWriteTextAnalyzer_GetGlyphPlacements(analyzer, aW, clustermap, textprops,
1971 len, glyphs, glyphprops, len, fontface, 1024.0, FALSE, FALSE, &sa, NULL, NULL,
1972 NULL, 0, advances, offsets);
1973 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1974 ok(advances[0] == 500.0, "got %.2f\n", advances[0]);
1975 ok(advances[1] == 500.0, "got %.2f\n", advances[1]);
1976 ok(offsets[0].advanceOffset == 0.0 && offsets[0].ascenderOffset == 0.0, "got %.2f,%.2f\n",
1977 offsets[0].advanceOffset, offsets[0].ascenderOffset);
1978
1979 advances[0] = advances[1] = 1.0;
1980 memset(offsets, 0xcc, sizeof(offsets));
1981 hr = IDWriteTextAnalyzer_GetGlyphPlacements(analyzer, aW, clustermap, textprops,
1982 len, glyphs, glyphprops, len, fontface, 20.48, FALSE, FALSE, &sa, NULL, NULL,
1983 NULL, 0, advances, offsets);
1984 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1985 ok(advances[0] == 10.0, "got %.2f\n", advances[0]);
1986 ok(advances[1] == 10.0, "got %.2f\n", advances[1]);
1987 ok(offsets[0].advanceOffset == 0.0 && offsets[0].ascenderOffset == 0.0, "got %.2f,%.2f\n",
1988 offsets[0].advanceOffset, offsets[0].ascenderOffset);
1989
1990 /* without clustermap */
1991 advances[0] = advances[1] = 1.0;
1992 hr = IDWriteTextAnalyzer_GetGlyphPlacements(analyzer, aW, NULL, textprops,
1993 len, glyphs, glyphprops, len, fontface, 1024.0, FALSE, FALSE, &sa, NULL, NULL,
1994 NULL, 0, advances, offsets);
1995 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1996 ok(advances[0] == 500.0, "got %.2f\n", advances[0]);
1997 ok(advances[1] == 500.0, "got %.2f\n", advances[1]);
1998
1999 /* it's happy to use negative size too */
2000 advances[0] = advances[1] = 1.0;
2001 memset(offsets, 0xcc, sizeof(offsets));
2002 hr = IDWriteTextAnalyzer_GetGlyphPlacements(analyzer, aW, clustermap, textprops,
2003 len, glyphs, glyphprops, len, fontface, -10.24, FALSE, FALSE, &sa, NULL, NULL,
2004 NULL, 0, advances, offsets);
2005 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2006 ok(advances[0] == -5.0, "got %.2f\n", advances[0]);
2007 ok(offsets[0].advanceOffset == 0.0 && offsets[0].ascenderOffset == 0.0, "got %.2f,%.2f\n",
2008 offsets[0].advanceOffset, offsets[0].ascenderOffset);
2009
2010 /* DWRITE_SCRIPT_SHAPES_NO_VISUAL has no effect on placement */
2012 advances[0] = advances[1] = 1.0f;
2013 memset(offsets, 0xcc, sizeof(offsets));
2014 hr = IDWriteTextAnalyzer_GetGlyphPlacements(analyzer, aW, clustermap, textprops,
2015 len, glyphs, glyphprops, len, fontface, 2048.0f, FALSE, FALSE, &sa, NULL, NULL,
2016 NULL, 0, advances, offsets);
2017 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2018 ok(advances[0] == 1000.0f, "got %.2f\n", advances[0]);
2019 ok(advances[1] == 1000.0f, "got %.2f\n", advances[1]);
2020 ok(offsets[0].advanceOffset == 0.0f && offsets[0].ascenderOffset == 0.0f, "got %.2f,%.2f\n",
2021 offsets[0].advanceOffset, offsets[0].ascenderOffset);
2022
2023 /* isZeroWidthSpace */
2025 advances[0] = advances[1] = 1.0f;
2026 memset(offsets, 0xcc, sizeof(offsets));
2027 glyphprops[0].isZeroWidthSpace = 1;
2028 hr = IDWriteTextAnalyzer_GetGlyphPlacements(analyzer, aW, clustermap, textprops,
2029 len, glyphs, glyphprops, len, fontface, 2048.0f, FALSE, FALSE, &sa, NULL, NULL,
2030 NULL, 0, advances, offsets);
2031 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2032 ok(advances[0] == 0.0f, "got %.2f\n", advances[0]);
2033 ok(advances[1] == 1000.0f, "got %.2f\n", advances[1]);
2034 ok(offsets[0].advanceOffset == 0.0f && offsets[0].ascenderOffset == 0.0f, "got %.2f,%.2f\n",
2035 offsets[0].advanceOffset, offsets[0].ascenderOffset);
2036
2037 IDWriteTextAnalyzer_Release(analyzer);
2038 IDWriteFontFace_Release(fontface);
2040}
@ DWRITE_SCRIPT_SHAPES_NO_VISUAL
Definition: dwrite.idl:330
@ DWRITE_SCRIPT_SHAPES_DEFAULT
Definition: dwrite.idl:329
static const WCHAR aW[]
Definition: htmlelem.c:21
#define DELETE_FONTFILE(filename)
Definition: analyzer.c:551
static IDWriteFontFace * create_testfontface(const WCHAR *filename)
Definition: analyzer.c:558
static WCHAR * create_testfontfile(const WCHAR *filename)
Definition: analyzer.c:526
static void get_script_analysis(const WCHAR *str, DWRITE_SCRIPT_ANALYSIS *sa)
Definition: analyzer.c:1085

Referenced by START_TEST().

◆ test_GetGlyphs()

static void test_GetGlyphs ( void  )
static

Definition at line 1662 of file analyzer.c.

1663{
1664 static const WCHAR test1W[] = {'<','B',' ','C',0};
1665 static const WCHAR test2W[] = {'<','B','\t','C',0};
1666 static const WCHAR test3W[] = {0x202a,0x202c,0};
1667 DWRITE_SHAPING_GLYPH_PROPERTIES shapingprops[20];
1669 UINT32 maxglyphcount, actual_count;
1670 FLOAT advances[10], advances2[10];
1671 IDWriteFontCollection *syscoll;
1672 IDWriteTextAnalyzer *analyzer;
1673 IDWriteFontFace *fontface;
1676 UINT16 clustermap[10];
1677 UINT16 glyphs1[10];
1678 UINT16 glyphs2[10];
1679 unsigned int i, j;
1680 HRESULT hr;
1681
1682 analyzer = create_text_analyzer(&IID_IDWriteTextAnalyzer);
1683 ok(!!analyzer, "Failed to create analyzer instance.\n");
1684
1685 fontface = create_fontface();
1686
1687 maxglyphcount = 1;
1688 sa.script = 0;
1690 hr = IDWriteTextAnalyzer_GetGlyphs(analyzer, test1W, lstrlenW(test1W), fontface, FALSE, FALSE, &sa, NULL,
1691 NULL, NULL, NULL, 0, maxglyphcount, clustermap, props, glyphs1, shapingprops, &actual_count);
1692 ok(hr == E_NOT_SUFFICIENT_BUFFER, "Unexpected hr %#lx.\n", hr);
1693
1694if (0) {
1695 /* NULL fontface - crashes on Windows */
1696 hr = IDWriteTextAnalyzer_GetGlyphs(analyzer, test1W, lstrlenW(test1W), NULL, FALSE, FALSE, &sa, NULL,
1697 NULL, NULL, NULL, 0, maxglyphcount, clustermap, props, glyphs1, shapingprops, &actual_count);
1698}
1699
1700 /* invalid script id */
1701 maxglyphcount = 10;
1702 actual_count = 0;
1703 sa.script = 999;
1705 hr = IDWriteTextAnalyzer_GetGlyphs(analyzer, test1W, lstrlenW(test1W), fontface, FALSE, FALSE, &sa, NULL,
1706 NULL, NULL, NULL, 0, maxglyphcount, clustermap, props, glyphs1, shapingprops, &actual_count);
1707 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1708 ok(actual_count == 4, "got %d\n", actual_count);
1709 ok(sa.script == 999, "got %u\n", sa.script);
1710
1711 /* no '\t' -> ' ' replacement */
1712 maxglyphcount = 10;
1713 actual_count = 0;
1714 hr = IDWriteTextAnalyzer_GetGlyphs(analyzer, test1W, lstrlenW(test1W), fontface, FALSE, FALSE, &sa, NULL,
1715 NULL, NULL, NULL, 0, maxglyphcount, clustermap, props, glyphs1, shapingprops, &actual_count);
1716 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1717 ok(actual_count == 4, "got %d\n", actual_count);
1718
1719 actual_count = 0;
1720 hr = IDWriteTextAnalyzer_GetGlyphs(analyzer, test2W, lstrlenW(test2W), fontface, FALSE, FALSE, &sa, NULL,
1721 NULL, NULL, NULL, 0, maxglyphcount, clustermap, props, glyphs2, shapingprops, &actual_count);
1722 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1723 ok(actual_count == 4, "got %d\n", actual_count);
1724 ok(glyphs1[2] != glyphs2[2], "got %d\n", glyphs1[2]);
1725
1726 /* check that mirroring works */
1727 maxglyphcount = 10;
1728 actual_count = 0;
1729 hr = IDWriteTextAnalyzer_GetGlyphs(analyzer, test1W, lstrlenW(test1W), fontface, FALSE, FALSE, &sa, NULL,
1730 NULL, NULL, NULL, 0, maxglyphcount, clustermap, props, glyphs1, shapingprops, &actual_count);
1731 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1732 ok(actual_count == 4, "got %d\n", actual_count);
1733
1734 actual_count = 0;
1735 hr = IDWriteTextAnalyzer_GetGlyphs(analyzer, test1W, lstrlenW(test1W), fontface, FALSE, TRUE, &sa, NULL,
1736 NULL, NULL, NULL, 0, maxglyphcount, clustermap, props, glyphs2, shapingprops, &actual_count);
1737 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1738 ok(actual_count == 4, "got %d\n", actual_count);
1739 ok(glyphs1[0] != glyphs2[0], "got %d\n", glyphs1[0]);
1740
1741 /* embedded control codes, with unknown script id 0 */
1742 get_fontface_glyphs(fontface, test3W, glyphs2);
1743 get_fontface_advances(fontface, 10.0, glyphs2, advances2, 2);
1744
1745 actual_count = 0;
1746 hr = IDWriteTextAnalyzer_GetGlyphs(analyzer, test3W, lstrlenW(test3W), fontface, FALSE, TRUE, &sa, NULL,
1747 NULL, NULL, NULL, 0, maxglyphcount, clustermap, props, glyphs1, shapingprops, &actual_count);
1748 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1749 ok(actual_count == 2, "got %d\n", actual_count);
1750 ok(glyphs1[0] == glyphs2[0], "got %u, expected %u\n", glyphs1[0], glyphs2[0]);
1751 ok(glyphs1[1] == glyphs2[1], "got %u, expected %u\n", glyphs1[1], glyphs2[1]);
1752 ok(shapingprops[0].isClusterStart == 1, "got %d\n", shapingprops[0].isClusterStart);
1753 ok(shapingprops[0].isZeroWidthSpace == 0, "got %d\n", shapingprops[0].isZeroWidthSpace);
1754 ok(shapingprops[1].isClusterStart == 1, "got %d\n", shapingprops[1].isClusterStart);
1755 ok(shapingprops[1].isZeroWidthSpace == 0, "got %d\n", shapingprops[1].isZeroWidthSpace);
1756 ok(clustermap[0] == 0, "got %d\n", clustermap[0]);
1757 ok(clustermap[1] == 1, "got %d\n", clustermap[1]);
1758
1759 memset(advances, 0, sizeof(advances));
1760 hr = IDWriteTextAnalyzer_GetGlyphPlacements(analyzer, test3W, clustermap, props, lstrlenW(test3W),
1761 glyphs1, shapingprops, actual_count, fontface, 10.0, FALSE, FALSE, &sa, NULL, NULL,
1762 NULL, 0, advances, offsets);
1763 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1764 ok(advances[0] == advances2[0], "got %.2f, expected %.2f\n", advances[0], advances2[0]);
1765 ok(advances[1] == advances2[1], "got %.2f, expected %.2f\n", advances[1], advances2[1]);
1766
1767 /* embedded control codes with proper script */
1768 sa.script = 0;
1769 get_script_analysis(test3W, &sa);
1770 ok(sa.script != 0, "got %d\n", sa.script);
1771 actual_count = 0;
1772 hr = IDWriteTextAnalyzer_GetGlyphs(analyzer, test3W, lstrlenW(test3W), fontface, FALSE, FALSE, &sa, NULL,
1773 NULL, NULL, NULL, 0, maxglyphcount, clustermap, props, glyphs1, shapingprops, &actual_count);
1774 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1775 ok(actual_count == 2, "got %d\n", actual_count);
1776 ok(glyphs1[0] == glyphs2[0], "got %u, expected %u\n", glyphs1[0], glyphs2[0]);
1777 ok(glyphs1[1] == glyphs2[1], "got %u, expected %u\n", glyphs1[1], glyphs2[1]);
1778 ok(shapingprops[0].isClusterStart == 1, "got %d\n", shapingprops[0].isClusterStart);
1779 ok(shapingprops[0].isZeroWidthSpace == 0, "got %d\n", shapingprops[0].isZeroWidthSpace);
1780 ok(shapingprops[1].isClusterStart == 1, "got %d\n", shapingprops[1].isClusterStart);
1781 ok(shapingprops[1].isZeroWidthSpace == 0, "got %d\n", shapingprops[1].isZeroWidthSpace);
1782 ok(clustermap[0] == 0, "got %d\n", clustermap[0]);
1783 ok(clustermap[1] == 1, "got %d\n", clustermap[1]);
1784
1785 memset(advances, 0, sizeof(advances));
1786 hr = IDWriteTextAnalyzer_GetGlyphPlacements(analyzer, test3W, clustermap, props, lstrlenW(test3W),
1787 glyphs1, shapingprops, actual_count, fontface, 10.0, FALSE, FALSE, &sa, NULL, NULL,
1788 NULL, 0, advances, offsets);
1789 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1790 ok(advances[0] == advances2[0], "got %.2f, expected %.2f\n", advances[0], advances2[0]);
1791 ok(advances[1] == advances2[1], "got %.2f, expected %.2f\n", advances[1], advances2[1]);
1792
1793 /* DWRITE_SCRIPT_SHAPES_NO_VISUAL run */
1794 maxglyphcount = 10;
1795 actual_count = 0;
1796 sa.script = 0;
1798 hr = IDWriteTextAnalyzer_GetGlyphs(analyzer, test1W, lstrlenW(test1W), fontface, FALSE, FALSE, &sa, NULL,
1799 NULL, NULL, NULL, 0, maxglyphcount, clustermap, props, glyphs1, shapingprops, &actual_count);
1800 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1801 ok(actual_count == 4, "got %d\n", actual_count);
1802 ok(sa.script == 0, "got %u\n", sa.script);
1803 ok(!shapingprops[0].isZeroWidthSpace, "got %d\n", shapingprops[0].isZeroWidthSpace);
1804
1805 IDWriteFontFace_Release(fontface);
1806
1807 /* Test setting glyph properties from GDEF. */
1808 hr = IDWriteFactory_GetSystemFontCollection(factory, &syscoll, FALSE);
1809 ok(hr == S_OK, "Failed to get system collection, hr %#lx.\n", hr);
1810
1811 for (i = 0; i < IDWriteFontCollection_GetFontFamilyCount(syscoll); ++i)
1812 {
1814 IDWriteFontFamily *family;
1815 WCHAR familyW[256];
1816
1817 hr = IDWriteFontCollection_GetFontFamily(syscoll, i, &family);
1818 ok(hr == S_OK, "Failed to get font family, hr %#lx.\n", hr);
1819
1820 hr = IDWriteFontFamily_GetFamilyNames(family, &names);
1821 ok(hr == S_OK, "Failed to get family names, hr %#lx.\n", hr);
1822 get_enus_string(names, familyW, ARRAY_SIZE(familyW));
1823 IDWriteLocalizedStrings_Release(names);
1824
1825 for (j = 0; j < IDWriteFontFamily_GetFontCount(family); ++j)
1826 {
1828 WCHAR faceW[256];
1829
1830 hr = IDWriteFontFamily_GetFont(family, j, &font);
1831 ok(hr == S_OK, "Failed to get font instance, hr %#lx.\n", hr);
1832
1833 hr = IDWriteFont_CreateFontFace(font, &fontface);
1834 ok(hr == S_OK, "Failed to create fontface, hr %#lx.\n", hr);
1835
1836 hr = IDWriteFont_GetFaceNames(font, &names);
1837 ok(hr == S_OK, "Failed to get face names, hr %#lx.\n", hr);
1838 get_enus_string(names, faceW, ARRAY_SIZE(faceW));
1839 IDWriteLocalizedStrings_Release(names);
1840
1841 test_glyph_props(analyzer, familyW, faceW, fontface);
1842
1843 IDWriteFontFace_Release(fontface);
1844 IDWriteFont_Release(font);
1845 }
1846
1847 IDWriteFontFamily_Release(family);
1848 }
1849
1850 IDWriteFontCollection_Release(syscoll);
1851
1852 IDWriteTextAnalyzer_Release(analyzer);
1853}
GLuint GLuint * names
Definition: glext.h:11545
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
static void get_fontface_advances(IDWriteFontFace *fontface, FLOAT emsize, const UINT16 *glyphs, FLOAT *advances, UINT32 count)
Definition: analyzer.c:1442
static void get_enus_string(IDWriteLocalizedStrings *strings, WCHAR *buff, unsigned int size)
Definition: analyzer.c:1549
static void get_fontface_glyphs(IDWriteFontFace *fontface, const WCHAR *str, UINT16 *glyphs)
Definition: analyzer.c:1430
static void test_glyph_props(IDWriteTextAnalyzer *analyzer, const WCHAR *family, const WCHAR *face, IDWriteFontFace *fontface)
Definition: analyzer.c:1566
#define E_NOT_SUFFICIENT_BUFFER
Definition: winerror.h:3437

Referenced by START_TEST().

◆ test_GetScriptProperties()

static void test_GetScriptProperties ( void  )
static

Definition at line 1262 of file analyzer.c.

1263{
1264 IDWriteTextAnalyzer1 *analyzer;
1267 HRESULT hr;
1268
1269 analyzer = create_text_analyzer(&IID_IDWriteTextAnalyzer1);
1270 if (!analyzer)
1271 {
1272 win_skip("GetScriptProperties() is not supported.\n");
1273 return;
1274 }
1275
1276 sa.script = 1000;
1277 hr = IDWriteTextAnalyzer1_GetScriptProperties(analyzer, sa, &props);
1278 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
1279
1280 if (0) /* Crashes on Windows */
1281 hr = IDWriteTextAnalyzer1_GetScriptProperties(analyzer, sa, NULL);
1282
1283 sa.script = 0;
1284 hr = IDWriteTextAnalyzer1_GetScriptProperties(analyzer, sa, &props);
1285 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1286
1287 IDWriteTextAnalyzer1_Release(analyzer);
1288}

Referenced by START_TEST().

◆ test_GetTextComplexity()

static void test_GetTextComplexity ( void  )
static

Definition at line 1320 of file analyzer.c.

1321{
1322 IDWriteTextAnalyzer1 *analyzer;
1323 IDWriteFontFace *fontface;
1324 UINT16 indices[10];
1325 BOOL simple;
1326 HRESULT hr;
1327 UINT32 len;
1328 int i;
1329
1330 analyzer = create_text_analyzer(&IID_IDWriteTextAnalyzer1);
1331 if (!analyzer)
1332 {
1333 win_skip("GetTextComplexity() is not supported.\n");
1334 return;
1335 }
1336
1337if (0) { /* crashes on native */
1338 hr = IDWriteTextAnalyzer1_GetTextComplexity(analyzer, NULL, 0, NULL, NULL, NULL, NULL);
1339 hr = IDWriteTextAnalyzer1_GetTextComplexity(analyzer, NULL, 0, NULL, NULL, &len, NULL);
1340 hr = IDWriteTextAnalyzer1_GetTextComplexity(analyzer, L"ABC", 3, NULL, NULL, NULL, NULL);
1341 hr = IDWriteTextAnalyzer1_GetTextComplexity(analyzer, L"ABC", 3, NULL, NULL, &len, NULL);
1342 hr = IDWriteTextAnalyzer1_GetTextComplexity(analyzer, L"ABC", 3, NULL, &simple, NULL, NULL);
1343}
1344
1345 len = 1;
1346 simple = TRUE;
1347 hr = IDWriteTextAnalyzer1_GetTextComplexity(analyzer, NULL, 0, NULL, &simple, &len, NULL);
1348 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
1349 ok(len == 0, "got %d\n", len);
1350 ok(simple == FALSE, "got %d\n", simple);
1351
1352 len = 1;
1353 simple = TRUE;
1354 indices[0] = 1;
1355 hr = IDWriteTextAnalyzer1_GetTextComplexity(analyzer, L"ABC", 3, NULL, &simple, &len, NULL);
1356 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
1357 ok(len == 0, "got %d\n", len);
1358 ok(simple == FALSE, "got %d\n", simple);
1359 ok(indices[0] == 1, "got %d\n", indices[0]);
1360
1361 fontface = create_fontface();
1362
1363 for (i = 0; i < ARRAY_SIZE(textcomplexity_tests); ++i)
1364 {
1366 len = 1;
1367 simple = !ptr->simple;
1368 indices[0] = 0;
1369 hr = IDWriteTextAnalyzer1_GetTextComplexity(analyzer, ptr->text, ptr->length, fontface, &simple, &len, indices);
1370 ok(hr == S_OK, "%d: Unexpected hr %#lx.\n", i, hr);
1371 ok(len == ptr->len_read, "%d: read length: got %d, expected %d\n", i, len, ptr->len_read);
1372 ok(simple == ptr->simple, "%d: simple: got %d, expected %d\n", i, simple, ptr->simple);
1373 if (simple && ptr->length)
1374 ok(indices[0] > 0, "%d: got %d\n", i, indices[0]);
1375 else
1376 ok(indices[0] == 0, "%d: got %d\n", i, indices[0]);
1377 }
1378
1379 IDWriteFontFace_Release(fontface);
1380 IDWriteTextAnalyzer1_Release(analyzer);
1381}
GLuint GLuint GLsizei GLenum const GLvoid * indices
Definition: gl.h:1545
static const struct textcomplexity_test textcomplexity_tests[]
Definition: analyzer.c:1297

Referenced by START_TEST().

◆ test_GetTypographicFeatures()

static void test_GetTypographicFeatures ( void  )
static

Definition at line 1855 of file analyzer.c.

1856{
1857 static const WCHAR arabicW[] = {0x064a,0x064f,0x0633,0};
1859 IDWriteTextAnalyzer2 *analyzer;
1860 IDWriteFontFace *fontface;
1862 UINT32 count;
1863 HRESULT hr;
1864
1865 analyzer = create_text_analyzer(&IID_IDWriteTextAnalyzer2);
1866 if (!analyzer)
1867 {
1868 win_skip("GetTypographicFeatures() is not supported.\n");
1869 return;
1870 }
1871
1872 fontface = create_fontface();
1873
1874 get_script_analysis(L"abc", &sa);
1875 count = 0;
1876 hr = IDWriteTextAnalyzer2_GetTypographicFeatures(analyzer, fontface, sa, NULL, 0, &count, NULL);
1877 ok(hr == E_NOT_SUFFICIENT_BUFFER, "Unexpected hr %#lx.\n", hr);
1878 ok(!!count, "Unexpected count %u.\n", count);
1879
1880 /* invalid locale name is ignored */
1881 get_script_analysis(L"abc", &sa);
1882 count = 0;
1883 hr = IDWriteTextAnalyzer2_GetTypographicFeatures(analyzer, fontface, sa, L"cadabra", 0, &count, NULL);
1884 ok(hr == E_NOT_SUFFICIENT_BUFFER, "Unexpected hr %#lx.\n", hr);
1885 ok(!!count, "Unexpected count %u.\n", count);
1886
1887 /* Make some calls for different scripts. */
1888
1889 get_script_analysis(arabicW, &sa);
1890 memset(tags, 0, sizeof(tags));
1891 count = 0;
1892 hr = IDWriteTextAnalyzer2_GetTypographicFeatures(analyzer, fontface, sa, NULL, ARRAY_SIZE(tags), &count, tags);
1893 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1894 ok(!!count, "Unexpected count %u.\n", count);
1895
1896 get_script_analysis(L"abc", &sa);
1897 memset(tags, 0, sizeof(tags));
1898 count = 0;
1899 hr = IDWriteTextAnalyzer2_GetTypographicFeatures(analyzer, fontface, sa, NULL, ARRAY_SIZE(tags), &count, tags);
1900 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1901 ok(!!count, "Unexpected count %u.\n", count);
1902
1903 IDWriteFontFace_Release(fontface);
1904 IDWriteTextAnalyzer2_Release(analyzer);
1905}
DWRITE_FONT_FEATURE_TAG
Definition: dwrite.idl:243
const char * tags[99]
Definition: apphelp.c:216

Referenced by START_TEST().

◆ test_glyph_justification_property()

static void test_glyph_justification_property ( void  )
static

Definition at line 2859 of file analyzer.c.

2860{
2861 static const struct
2862 {
2863 enum script_id script;
2864 const WCHAR *text;
2865 unsigned short justification[10];
2866 } tests[] =
2867 {
2868 {
2870 L"a b\tc",
2871 {
2877 },
2878 },
2879 {
2881 L" a b",
2882 {
2887 },
2888 },
2889 {
2891 L" a b",
2892 {
2897 },
2898 },
2900 { Script_Latin, L"\x640", { SCRIPT_JUSTIFY_CHARACTER } },
2902
2907
2909
2913
2915 };
2916 DWRITE_SHAPING_GLYPH_PROPERTIES glyph_props[16];
2917 DWRITE_SHAPING_TEXT_PROPERTIES text_props[16];
2918 UINT16 clustermap[16], glyphs[16];
2919 IDWriteTextAnalyzer *analyzer;
2921 IDWriteFontFace *fontface;
2922 UINT32 glyph_count;
2923 unsigned int i, j;
2924 HRESULT hr;
2925
2926 analyzer = create_text_analyzer(&IID_IDWriteTextAnalyzer);
2927 ok(!!analyzer, "Failed to create analyzer instance.\n");
2928
2929 fontface = create_fontface();
2930
2931 for (i = 0; i < ARRAY_SIZE(tests); ++i)
2932 {
2933 if (tests[i].script == Script_Arabic && !strcmp(winetest_platform, "wine"))
2934 continue;
2935
2937
2938 sa.script = tests[i].script;
2940
2941 /* Use RTL for Arabic, it affects returned justification classes. */
2942 hr = IDWriteTextAnalyzer_GetGlyphs(analyzer, tests[i].text, wcslen(tests[i].text), fontface,
2943 FALSE, sa.script == Script_Arabic, &sa, L"en-US", NULL, NULL, NULL, 0, ARRAY_SIZE(glyphs), clustermap,
2944 text_props, glyphs, glyph_props, &glyph_count);
2945 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2946
2947 for (j = 0; j < glyph_count; ++j)
2948 {
2949 winetest_push_context("Glyph %u", j);
2950 ok(glyph_props[j].justification == tests[i].justification[j], "Unexpected justification value %u.\n",
2951 glyph_props[j].justification);
2953 }
2954
2956 }
2957
2958 IDWriteFontFace_Release(fontface);
2959}
_ACRTIMP size_t __cdecl wcslen(const wchar_t *)
Definition: wcs.c:2988
_ACRTIMP int __cdecl strcmp(const char *, const char *)
Definition: string.c:3324
@ SCRIPT_JUSTIFY_ARABIC_HA
@ SCRIPT_JUSTIFY_ARABIC_SEEN
@ SCRIPT_JUSTIFY_ARABIC_BLANK
@ SCRIPT_JUSTIFY_ARABIC_NORMAL
@ SCRIPT_JUSTIFY_ARABIC_SEEN_M
@ SCRIPT_JUSTIFY_NONE
@ SCRIPT_JUSTIFY_ARABIC_BARA
@ SCRIPT_JUSTIFY_BLANK
@ SCRIPT_JUSTIFY_CHARACTER
@ SCRIPT_JUSTIFY_ARABIC_ALEF
@ SCRIPT_JUSTIFY_ARABIC_KASHIDA
#define debugstr_w
Definition: kernel32.h:32
const char * winetest_platform
static struct test_info tests[]
script_id
Definition: analyzer.c:2853
script
Definition: msipriv.h:396

Referenced by START_TEST().

◆ test_glyph_props()

static void test_glyph_props ( IDWriteTextAnalyzer *  analyzer,
const WCHAR *  family,
const WCHAR *  face,
IDWriteFontFace *  fontface 
)
static

Definition at line 1566 of file analyzer.c.

1568{
1569 unsigned int i, ch, count, offset;
1570 struct dwrite_fonttable gdef;
1571 DWRITE_UNICODE_RANGE *ranges;
1572 IDWriteFontFace1 *fontface1;
1573 BOOL exists = FALSE;
1574 HRESULT hr;
1575
1576 hr = IDWriteFontFace_TryGetFontTable(fontface, MS_GDEF_TAG, (const void **)&gdef.data, &gdef.size,
1577 &gdef.context, &exists);
1578 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1579
1580 if (!exists)
1581 return;
1582
1583 offset = table_read_be_word(&gdef, 4);
1584 if (!offset)
1585 {
1586 IDWriteFontFace_ReleaseFontTable(fontface, gdef.context);
1587 return;
1588 }
1589
1590 if (FAILED(IDWriteFontFace_QueryInterface(fontface, &IID_IDWriteFontFace1, (void **)&fontface1)))
1591 {
1592 IDWriteFontFace_ReleaseFontTable(fontface, gdef.context);
1593 return;
1594 }
1595
1596 hr = IDWriteFontFace1_GetUnicodeRanges(fontface1, 0, NULL, &count);
1597 ok(hr == E_NOT_SUFFICIENT_BUFFER, "Unexpected hr %#lx.\n", hr);
1598
1599 ranges = malloc(count * sizeof(*ranges));
1600
1601 hr = IDWriteFontFace1_GetUnicodeRanges(fontface1, count, ranges, &count);
1602 ok(hr == S_OK, "Failed to get ranges, hr %#lx.\n", hr);
1603
1604 for (i = 0; i < count; ++i)
1605 {
1606 if (ranges[i].first > 0xffff)
1607 break;
1608
1609 for (ch = ranges[i].first; ch <= ranges[i].last; ch++)
1610 {
1611 DWRITE_SHAPING_TEXT_PROPERTIES text_props[10];
1612 DWRITE_SHAPING_GLYPH_PROPERTIES glyph_props[10];
1613 UINT16 glyphs[10], clustermap[10], glyph;
1614 unsigned int actual_count, glyph_class;
1616 WCHAR text[1];
1617
1618 hr = IDWriteFontFace1_GetGlyphIndices(fontface1, &ch, 1, &glyph);
1619 ok(hr == S_OK, "Failed to get glyph index, hr %#lx.\n", hr);
1620
1621 if (!glyph)
1622 continue;
1623
1624 sa.script = 999;
1626 text[0] = (WCHAR)ch;
1627 memset(glyph_props, 0, sizeof(glyph_props));
1628 hr = IDWriteTextAnalyzer_GetGlyphs(analyzer, text, 1, fontface, FALSE, FALSE, &sa, NULL,
1629 NULL, NULL, NULL, 0, ARRAY_SIZE(glyphs), clustermap, text_props, glyphs, glyph_props, &actual_count);
1630 ok(hr == S_OK, "Failed to shape, hr %#lx.\n", hr);
1631 if (actual_count > 1)
1632 continue;
1633
1634 glyph_class = get_glyph_class(&gdef, glyphs[0]);
1635
1636 switch (glyph_class)
1637 {
1638 case GDEF_CLASS_MARK:
1639 ok(glyph_props[0].isDiacritic && glyph_props[0].isZeroWidthSpace,
1640 "%#x -> %u: unexpected glyph properties %u/%u. Class %u. Font %s - %s.\n",
1641 text[0], glyphs[0], glyph_props[0].isDiacritic, glyph_props[0].isZeroWidthSpace,
1642 glyph_class, wine_dbgstr_w(family), wine_dbgstr_w(face));
1643 break;
1644 default:
1645 break;
1646 }
1647
1648 if (glyph_props[0].isDiacritic)
1649 ok(glyph_props[0].isZeroWidthSpace,
1650 "%#x -> %u: unexpected glyph properties %u/%u. Class %u. Font %s - %s.\n", text[0], glyphs[0],
1651 glyph_props[0].isDiacritic, glyph_props[0].isZeroWidthSpace, glyph_class,
1652 wine_dbgstr_w(family), wine_dbgstr_w(face));
1653 }
1654 }
1655
1656 free(ranges);
1657
1658 IDWriteFontFace_ReleaseFontTable(fontface, gdef.context);
1659 IDWriteFontFace1_Release(fontface1);
1660}
unsigned char ch[4][2]
Definition: console.c:118
const GLint * first
Definition: glext.h:5794
#define FAILED(hr)
Definition: intsafe.h:51
#define MS_GDEF_TAG
Definition: analyzer.c:62
static unsigned int get_glyph_class(const struct dwrite_fonttable *table, UINT16 glyph)
Definition: analyzer.c:1503

Referenced by test_GetGlyphs().

◆ test_numbersubstitution()

static void test_numbersubstitution ( void  )
static

Definition at line 1383 of file analyzer.c.

1384{
1385 IDWriteNumberSubstitution *substitution;
1386 HRESULT hr;
1387
1388 /* locale is not specified, method does not require it */
1389 hr = IDWriteFactory_CreateNumberSubstitution(factory, DWRITE_NUMBER_SUBSTITUTION_METHOD_NONE, NULL, FALSE, &substitution);
1390 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1391 IDWriteNumberSubstitution_Release(substitution);
1392
1393 /* invalid locale name, method does not require it */
1394 hr = IDWriteFactory_CreateNumberSubstitution(factory, DWRITE_NUMBER_SUBSTITUTION_METHOD_NONE, L"dummy",
1395 FALSE, &substitution);
1396 ok(hr == S_OK, "Failed to create number substitution, hr %#lx.\n", hr);
1397 IDWriteNumberSubstitution_Release(substitution);
1398
1399 /* invalid method */
1400 hr = IDWriteFactory_CreateNumberSubstitution(factory, DWRITE_NUMBER_SUBSTITUTION_METHOD_TRADITIONAL+1, NULL, FALSE, &substitution);
1401 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
1402
1403 /* invalid method */
1404 hr = IDWriteFactory_CreateNumberSubstitution(factory, -1, NULL, FALSE, &substitution);
1405 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
1406
1407 /* invalid locale */
1408 hr = IDWriteFactory_CreateNumberSubstitution(factory, DWRITE_NUMBER_SUBSTITUTION_METHOD_TRADITIONAL, NULL, FALSE, &substitution);
1409 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
1410
1411 hr = IDWriteFactory_CreateNumberSubstitution(factory, DWRITE_NUMBER_SUBSTITUTION_METHOD_TRADITIONAL, L"dummy",
1412 FALSE, &substitution);
1413 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
1414
1415 hr = IDWriteFactory_CreateNumberSubstitution(factory, DWRITE_NUMBER_SUBSTITUTION_METHOD_CONTEXTUAL, L"dummy",
1416 FALSE, &substitution);
1417 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
1418
1419 hr = IDWriteFactory_CreateNumberSubstitution(factory, DWRITE_NUMBER_SUBSTITUTION_METHOD_NATIONAL, L"dummy",
1420 FALSE, &substitution);
1421 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
1422
1423 /* invalid locale, but it's not needed for this method */
1424 hr = IDWriteFactory_CreateNumberSubstitution(factory, DWRITE_NUMBER_SUBSTITUTION_METHOD_NONE, L"dummy", FALSE,
1425 &substitution);
1426 ok(hr == S_OK, "Failed to create number substitution, hr %#lx.\n", hr);
1427 IDWriteNumberSubstitution_Release(substitution);
1428}
@ DWRITE_NUMBER_SUBSTITUTION_METHOD_NONE
Definition: dwrite.idl:338
@ DWRITE_NUMBER_SUBSTITUTION_METHOD_CONTEXTUAL
Definition: dwrite.idl:337
@ DWRITE_NUMBER_SUBSTITUTION_METHOD_TRADITIONAL
Definition: dwrite.idl:340
@ DWRITE_NUMBER_SUBSTITUTION_METHOD_NATIONAL
Definition: dwrite.idl:339

Referenced by START_TEST().

◆ test_uint()

static void test_uint ( UINT32  actual,
UINT32  expected,
const char *  name,
const struct testcontext *  ctxt 
)
static

Definition at line 183 of file analyzer.c.

184{
185 if (expected != actual && ctxt->todo)
186 {
187 (*ctxt->failcount)++;
188 ok_(ctxt->file, ctxt->line) (0, "%s: \"%s\" expecting %u, got %u\n", get_analysis_kind_name(ctxt->kind), name, expected, actual);
189 }
190 else
191 ok_(ctxt->file, ctxt->line) (expected == actual, "%s: \"%s\" expecting %u, got %u\n", get_analysis_kind_name(ctxt->kind), name,
192 expected, actual);
193}
Definition: name.c:39
enum analysis_kind kind
Definition: analyzer.c:126
BOOL todo
Definition: analyzer.c:127

Referenced by ok_sequence_().

Variable Documentation

◆ analysissink

IDWriteTextAnalysisSink analysissink = { &analysissinkvtbl }
static

Definition at line 392 of file analyzer.c.

Referenced by test_AnalyzeBidi(), test_AnalyzeLineBreakpoints(), and test_AnalyzeScript().

◆ analysissink2

IDWriteTextAnalysisSink analysissink2 = { &analysissinkvtbl2 }
static

Definition at line 393 of file analyzer.c.

Referenced by get_script_analysis().

◆ analysissinkvtbl

IDWriteTextAnalysisSinkVtbl analysissinkvtbl
static
Initial value:
= {
}
static HRESULT WINAPI analysissink_SetBidiLevel(IDWriteTextAnalysisSink *iface, UINT32 position, UINT32 length, UINT8 explicitLevel, UINT8 resolvedLevel)
Definition: analyzer.c:348
static HRESULT WINAPI analysissink_SetNumberSubstitution(IDWriteTextAnalysisSink *iface, UINT32 position, UINT32 length, IDWriteNumberSubstitution *substitution)
Definition: analyzer.c:363
static HRESULT WINAPI analysissink_SetLineBreakpoints(IDWriteTextAnalysisSink *iface, UINT32 position, UINT32 length, DWRITE_LINE_BREAKPOINT const *breakpoints)
Definition: analyzer.c:332
static ULONG WINAPI analysissink_Release(IDWriteTextAnalysisSink *iface)
Definition: analyzer.c:304
static HRESULT WINAPI analysissink_SetScriptAnalysis(IDWriteTextAnalysisSink *iface, UINT32 position, UINT32 length, DWRITE_SCRIPT_ANALYSIS const *sa)
Definition: analyzer.c:309
static ULONG WINAPI analysissink_AddRef(IDWriteTextAnalysisSink *iface)
Definition: analyzer.c:299
static HRESULT WINAPI analysissink_QueryInterface(IDWriteTextAnalysisSink *iface, REFIID riid, void **obj)
Definition: analyzer.c:287

Definition at line 372 of file analyzer.c.

◆ analysissinkvtbl2

IDWriteTextAnalysisSinkVtbl analysissinkvtbl2
static
Initial value:
= {
}
static HRESULT WINAPI analysissink_SetScriptAnalysis2(IDWriteTextAnalysisSink *iface, UINT32 position, UINT32 length, DWRITE_SCRIPT_ANALYSIS const *sa)
Definition: analyzer.c:322

Definition at line 382 of file analyzer.c.

◆ analysissource

◆ analysissourcevtbl

IDWriteTextAnalysisSourceVtbl analysissourcevtbl
static
Initial value:
= {
}
static DWRITE_READING_DIRECTION WINAPI analysissource_GetParagraphReadingDirection(IDWriteTextAnalysisSource *iface)
Definition: analyzer.c:461
static ULONG WINAPI analysissource_Release(IDWriteTextAnalysisSource *iface)
Definition: analyzer.c:408
static HRESULT WINAPI analysissource_GetNumberSubstitution(IDWriteTextAnalysisSource *iface, UINT32 position, UINT32 *text_len, IDWriteNumberSubstitution **substitution)
Definition: analyzer.c:476
static ULONG WINAPI analysissource_AddRef(IDWriteTextAnalysisSource *iface)
Definition: analyzer.c:402
static HRESULT WINAPI analysissource_GetTextAtPosition(IDWriteTextAnalysisSource *iface, UINT32 position, WCHAR const **text, UINT32 *text_len)
Definition: analyzer.c:435
static HRESULT WINAPI analysissource_QueryInterface(IDWriteTextAnalysisSource *iface, REFIID riid, void **obj)
Definition: analyzer.c:395
static HRESULT WINAPI analysissource_GetLocaleName(IDWriteTextAnalysisSource *iface, UINT32 position, UINT32 *text_len, WCHAR const **locale)
Definition: analyzer.c:468
static HRESULT WINAPI analysissource_GetTextBeforePosition(IDWriteTextAnalysisSource *iface, UINT32 position, WCHAR const **text, UINT32 *text_len)
Definition: analyzer.c:454

Definition at line 483 of file analyzer.c.

◆ bidi_tests

const struct bidi_test bidi_tests[]
static

Definition at line 2654 of file analyzer.c.

Referenced by test_AnalyzeBidi().

◆ expected_seq

struct call_sequence* expected_seq[1]
static

Definition at line 143 of file analyzer.c.

Referenced by START_TEST(), and test_AnalyzeScript().

◆ factory

Definition at line 36 of file analyzer.c.

◆ g_actual_bp

◆ g_explicit_levels

UINT8 g_explicit_levels[BIDI_LEVELS_COUNT]
static

Definition at line 346 of file analyzer.c.

Referenced by analysissink_SetBidiLevel(), and test_AnalyzeBidi().

◆ g_resolved_levels

UINT8 g_resolved_levels[BIDI_LEVELS_COUNT]
static

Definition at line 347 of file analyzer.c.

Referenced by analysissink_SetBidiLevel(), and test_AnalyzeBidi().

◆ g_sa

Definition at line 321 of file analyzer.c.

Referenced by analysissink_SetScriptAnalysis2(), and get_script_analysis().

◆ linebreaks_tests

const struct linebreaks_test linebreaks_tests[]
static

Definition at line 1138 of file analyzer.c.

Referenced by test_AnalyzeLineBreakpoints().

◆ ot_tests

Initial value:
= {
{ DWRITE_GLYPH_ORIENTATION_ANGLE_0_DEGREES, FALSE, { 1.0, 0.0, 0.0, 1.0, 0.0, 0.0 } },
{ DWRITE_GLYPH_ORIENTATION_ANGLE_90_DEGREES, FALSE, { 0.0, 1.0, -1.0, 0.0, 0.0, 0.0 } },
{ DWRITE_GLYPH_ORIENTATION_ANGLE_180_DEGREES, FALSE, { -1.0, 0.0, 0.0, -1.0, 0.0, 0.0 } },
{ DWRITE_GLYPH_ORIENTATION_ANGLE_270_DEGREES, FALSE, { 0.0, -1.0, 1.0, 0.0, 0.0, 0.0 } },
{ DWRITE_GLYPH_ORIENTATION_ANGLE_0_DEGREES, TRUE, { 0.0, 1.0, -1.0, 0.0, 0.0, 0.0 } },
{ DWRITE_GLYPH_ORIENTATION_ANGLE_90_DEGREES, TRUE, { -1.0, 0.0, 0.0, -1.0, 0.0, 0.0 } },
{ DWRITE_GLYPH_ORIENTATION_ANGLE_180_DEGREES, TRUE, { 0.0, -1.0, 1.0, 0.0, 0.0, 0.0 } },
{ DWRITE_GLYPH_ORIENTATION_ANGLE_270_DEGREES, TRUE, { 1.0, 0.0, 0.0, 1.0, 0.0, 0.0 } }
}

Definition at line 2360 of file analyzer.c.

Referenced by test_GetGlyphOrientationTransform().

◆ sa_tests

struct sa_test sa_tests[]
static

Definition at line 582 of file analyzer.c.

Referenced by test_AnalyzeScript().

◆ sequences

Definition at line 142 of file analyzer.c.

Referenced by analysissink_SetScriptAnalysis(), START_TEST(), and test_AnalyzeScript().

◆ spacing_tests

const struct spacing_test spacing_tests[]
static

Definition at line 2054 of file analyzer.c.

Referenced by test_ApplyCharacterSpacing().

◆ textcomplexity_tests

const struct textcomplexity_test textcomplexity_tests[]
static
Initial value:
= {
{ {0}, 1, FALSE, 1 },
{ {0}, 0, TRUE, 0 },
{ {0x610,0}, 0, TRUE, 0 },
{ {'A','B','C','D',0}, 3, TRUE, 3 },
{ {'A','B','C','D',0}, 5, TRUE, 4 },
{ {'A','B','C','D',0}, 10, TRUE, 4 },
{ {'A',0x610,'C','D',0}, 1, TRUE, 1 },
{ {'A',0x610,'C','D',0}, 2, FALSE, 2 },
{ {0x610,'A','C','D',0}, 1, FALSE, 1 },
{ {0x610,'A','C','D',0}, 2, FALSE, 1 },
{ {0x610,0x610,'C','D',0}, 2, FALSE, 2 },
{ {0xd800,'A','B',0}, 1, FALSE, 1 },
{ {0xd800,'A','B',0}, 2, FALSE, 1 },
{ {0xdc00,'A','B',0}, 2, FALSE, 1 },
{ {0x202a,'A',0x202c,0}, 3, FALSE, 1 },
{ {0x200e,'A',0}, 2, FALSE, 1 },
{ {0x200f,'A',0}, 2, FALSE, 1 },
{ {0x202d,'A',0}, 2, FALSE, 1 },
{ {0x202e,'A',0}, 2, FALSE, 1 },
}

Definition at line 1297 of file analyzer.c.

Referenced by test_GetTextComplexity().