dwrite: Fix spans length reported by AnalyzeScript() for characters above BMP.

Signed-off-by: Nikolay Sivov <nsivov@codeweavers.com>
This commit is contained in:
Nikolay Sivov 2022-09-02 19:56:31 +03:00 committed by Alexandre Julliard
parent 12d0792f74
commit eddf252aff
2 changed files with 24 additions and 15 deletions

View file

@ -375,6 +375,11 @@ struct text_source_context
UINT32 ch;
};
static inline unsigned int text_source_get_char_length(const struct text_source_context *context)
{
return context->ch > 0xffff ? 2 : 1;
}
static void text_source_read_more(struct text_source_context *context)
{
if ((context->chunk_length - context->cursor) > 1) return;
@ -674,14 +679,15 @@ static DWRITE_SCRIPT_ANALYSIS get_char_sa(UINT32 c)
static HRESULT analyze_script(struct text_source_context *context, IDWriteTextAnalysisSink *sink)
{
DWRITE_SCRIPT_ANALYSIS sa;
UINT32 pos, seq_length;
UINT32 pos, length;
HRESULT hr;
text_source_get_next_u32_char(context);
sa = get_char_sa(context->ch);
pos = context->position;
seq_length = 1;
length = text_source_get_char_length(context);
while (!text_source_get_next_u32_char(context))
{
@ -705,20 +711,19 @@ static HRESULT analyze_script(struct text_source_context *context, IDWriteTextAn
/* this is a length of a sequence to be reported next */
if (sa.script == cur_sa.script && sa.shapes == cur_sa.shapes)
seq_length++;
else {
HRESULT hr;
hr = IDWriteTextAnalysisSink_SetScriptAnalysis(sink, pos, seq_length, &sa);
length += text_source_get_char_length(context);
else
{
hr = IDWriteTextAnalysisSink_SetScriptAnalysis(sink, pos, length, &sa);
if (FAILED(hr)) return hr;
pos += seq_length;
seq_length = 1;
pos += length;
length = text_source_get_char_length(context);
sa = cur_sa;
}
}
/* one char length case or normal completion call */
return IDWriteTextAnalysisSink_SetScriptAnalysis(sink, pos, seq_length, &sa);
return IDWriteTextAnalysisSink_SetScriptAnalysis(sink, pos, length, &sa);
}
struct linebreaking_state {
@ -2379,11 +2384,6 @@ static inline BOOL fallback_is_uvs(const struct text_source_context *context)
return FALSE;
}
static inline unsigned int text_source_get_char_length(const struct text_source_context *context)
{
return context->ch > 0xffff ? 2 : 1;
}
static UINT32 fallback_font_get_supported_length(IDWriteFont3 *font, IDWriteTextAnalysisSource *source,
UINT32 position, UINT32 length)
{

View file

@ -1021,6 +1021,11 @@ static struct sa_test sa_tests[] = {
{0x25cc,0x300,'a',0}, 1,
{ { 0, 3, DWRITE_SCRIPT_SHAPES_DEFAULT } }
},
{
/* TAKRI LETTER A U+11680 */
{0xd805,0xde80,0}, 1,
{ { 0, 2, DWRITE_SCRIPT_SHAPES_DEFAULT } }
},
/* keep this as end test data marker */
{ {0} }
};
@ -1080,12 +1085,16 @@ static void test_AnalyzeScript(void)
{
init_textsource(&analysissource, ptr->string, DWRITE_READING_DIRECTION_LEFT_TO_RIGHT);
winetest_push_context("Test %s", debugstr_w(ptr->string));
init_expected_sa(expected_seq, ptr);
hr = IDWriteTextAnalyzer_AnalyzeScript(analyzer, &analysissource.IDWriteTextAnalysisSource_iface, 0,
lstrlenW(ptr->string), &analysissink);
ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
ok_sequence(sequences, ANALYZER_ID, expected_seq[0]->sequence, wine_dbgstr_w(ptr->string), FALSE);
ptr++;
winetest_pop_context();
}
IDWriteTextAnalyzer_Release(analyzer);