From: Jactry Zeng jzeng@codeweavers.com
Signed-off-by: Jactry Zeng jzeng@codeweavers.com --- dlls/riched20/editor.h | 11 +++++++++ dlls/riched20/editstr.h | 1 + dlls/riched20/run.c | 2 ++ dlls/riched20/wrap.c | 49 ++++++++++++++++++++++++++++++++--------- 4 files changed, 52 insertions(+), 11 deletions(-)
diff --git a/dlls/riched20/editor.h b/dlls/riched20/editor.h index e3f196c8bdc..c4be5eed88b 100644 --- a/dlls/riched20/editor.h +++ b/dlls/riched20/editor.h @@ -36,6 +36,12 @@ extern HINSTANCE dll_instance DECLSPEC_HIDDEN; (fe).lindex=-1;\ };
+#define MAKE_OPENTYPE_TAG( _x1, _x2, _x3, _x4 ) \ + ( ( (ULONG)_x4 << 24 ) | \ + ( (ULONG)_x3 << 16 ) | \ + ( (ULONG)_x2 << 8 ) | \ + (ULONG)_x1 ) + static inline WCHAR *get_text( const ME_Run *run, int offset ) { return run->para->text->szData + run->nCharOfs + offset; @@ -46,6 +52,11 @@ static inline const char *debugstr_run( const ME_Run *run ) return debugstr_wn( get_text( run, 0 ), run->len ); }
+static inline const char *debugstr_tag( OPENTYPE_TAG tag ) +{ + return debugstr_an( (char *)&tag, 4 ); +} + /* style.c */ ME_Style *style_get_insert_style( ME_TextEditor *editor, ME_Cursor *cursor ) DECLSPEC_HIDDEN; ME_Style *ME_MakeStyle(CHARFORMAT2W *style) DECLSPEC_HIDDEN; diff --git a/dlls/riched20/editstr.h b/dlls/riched20/editstr.h index 3b166234f23..683a83e7154 100644 --- a/dlls/riched20/editstr.h +++ b/dlls/riched20/editstr.h @@ -176,6 +176,7 @@ typedef struct tagME_Run GOFFSET *offsets; int max_clusters; WORD *clusters; + OPENTYPE_TAG script_tag; } ME_Run;
typedef struct tagME_Border diff --git a/dlls/riched20/run.c b/dlls/riched20/run.c index 2fc498571b8..0a81acdec8a 100644 --- a/dlls/riched20/run.c +++ b/dlls/riched20/run.c @@ -314,6 +314,7 @@ ME_Run *run_split( ME_TextEditor *editor, ME_Cursor *cursor ) new_run->nCharOfs = run->nCharOfs + nOffset; new_run->len = run->len - nOffset; new_run->para = run->para; + new_run->script_tag = run->script_tag; run->len = nOffset; cursor->run = new_run; cursor->nOffset = 0; @@ -361,6 +362,7 @@ ME_Run *run_create( ME_Style *s, int flags ) run->offsets = NULL; run->max_clusters = 0; run->clusters = NULL; + run->script_tag = 0; return run; }
diff --git a/dlls/riched20/wrap.c b/dlls/riched20/wrap.c index db3e2806239..2c2ee46371f 100644 --- a/dlls/riched20/wrap.c +++ b/dlls/riched20/wrap.c @@ -63,6 +63,8 @@ static BOOL get_run_glyph_buffers( ME_Run *run )
static HRESULT shape_run( ME_Context *c, ME_Run *run ) { + SCRIPT_GLYPHPROP *glyph_prop; + SCRIPT_CHARPROP *char_prop; HRESULT hr; int i;
@@ -80,11 +82,20 @@ static HRESULT shape_run( ME_Context *c, ME_Run *run ) run->clusters = heap_alloc( run->max_clusters * sizeof(WORD) ); }
+ if (!(char_prop = heap_alloc( run->len * sizeof( *char_prop ) ))) + return E_OUTOFMEMORY; + if (!(glyph_prop = heap_alloc( run->len * sizeof( *glyph_prop ) ))) + { + heap_free( char_prop ); + return E_OUTOFMEMORY; + } + select_style( c, run->style ); while (1) { - hr = ScriptShape( c->hDC, &run->style->script_cache, get_text( run, 0 ), run->len, run->max_glyphs, - &run->script_analysis, run->glyphs, run->clusters, run->vis_attrs, &run->num_glyphs ); + hr = ScriptShapeOpenType( c->hDC, &run->style->script_cache, &run->script_analysis, run->script_tag, 0, + NULL, NULL, 0, get_text( run, 0 ), run->len, run->max_glyphs, run->clusters, + char_prop, run->glyphs, glyph_prop, &run->num_glyphs ); if (hr != E_OUTOFMEMORY) break; if (run->max_glyphs > 10 * run->len) break; /* something has clearly gone wrong */ run->max_glyphs *= 2; @@ -92,8 +103,12 @@ static HRESULT shape_run( ME_Context *c, ME_Run *run ) }
if (SUCCEEDED(hr)) - hr = ScriptPlace( c->hDC, &run->style->script_cache, run->glyphs, run->num_glyphs, run->vis_attrs, - &run->script_analysis, run->advances, run->offsets, NULL ); + hr = ScriptPlaceOpenType( c->hDC, &run->style->script_cache, &run->script_analysis, run->script_tag, 0, + NULL, NULL, 0, get_text( run, 0 ), run->clusters, char_prop, run->len, run->glyphs, + glyph_prop, run->num_glyphs, run->advances, run->offsets, NULL ); + + heap_free( char_prop ); + heap_free( glyph_prop );
if (SUCCEEDED(hr)) { @@ -725,6 +740,7 @@ static HRESULT itemize_para( ME_Context *c, ME_Paragraph *para ) { ME_Run *run; SCRIPT_ITEM buf[16], *items = buf; + OPENTYPE_TAG tags[16], *script_tags = tags; int items_passed = ARRAY_SIZE( buf ), num_items, cur_item; SCRIPT_CONTROL control = { LANG_USER_DEFAULT, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, 0 }; @@ -738,16 +754,23 @@ static HRESULT itemize_para( ME_Context *c, ME_Paragraph *para )
while (1) { - hr = ScriptItemize( para->text->szData, para->text->nLen, items_passed, &control, - &state, items, &num_items ); + hr = ScriptItemizeOpenType( para->text->szData, para->text->nLen, items_passed, &control, + &state, items, script_tags, &num_items ); + if (hr != E_OUTOFMEMORY) break; /* may not be enough items if hr == E_OUTOFMEMORY */ if (items_passed > para->text->nLen + 1) break; /* something else has gone wrong */ items_passed *= 2; if (items == buf) + { items = heap_alloc( items_passed * sizeof( *items ) ); + script_tags = heap_alloc( items_passed * sizeof( *script_tags ) ); + } else + { items = heap_realloc( items, items_passed * sizeof( *items ) ); - if (!items) break; + script_tags = heap_realloc( script_tags, items_passed * sizeof( *script_tags ) ); + } + if (!items || !script_tags) break; } if (FAILED( hr )) goto end;
@@ -760,9 +783,10 @@ static HRESULT itemize_para( ME_Context *c, ME_Paragraph *para ) items[cur_item].a.fRTL, items[cur_item].a.s.uBidiLevel ); }
- TRACE( "before splitting runs into ranges\n" ); + TRACE( "before splitting runs into ranges:\n" ); for (run = para_first_run( para ); run; run = run_next( run )) - TRACE( "\t%d: %s\n", run->nCharOfs, debugstr_run( run ) ); + TRACE( "\t%d %s: %s\n", run->nCharOfs, run->script_tag ? debugstr_tag( run->script_tag ) : " ", + debugstr_run( run ) ); }
/* split runs into ranges at item boundaries */ @@ -772,6 +796,7 @@ static HRESULT itemize_para( ME_Context *c, ME_Paragraph *para )
items[cur_item].a.fLogicalOrder = TRUE; run->script_analysis = items[cur_item].a; + run->script_tag = script_tags[cur_item];
if (run->nFlags & MERF_ENDPARA) break; /* don't split eop runs */
@@ -784,15 +809,17 @@ static HRESULT itemize_para( ME_Context *c, ME_Paragraph *para )
if (TRACE_ON( richedit )) { - TRACE( "after splitting into ranges\n" ); + TRACE( "after splitting runs into ranges:\n" ); for (run = para_first_run( para ); run; run = run_next( run )) - TRACE( "\t%d: %s\n", run->nCharOfs, debugstr_run( run ) ); + TRACE( "\t%d %s: %s\n", run->nCharOfs, run->script_tag ? debugstr_tag( run->script_tag ) : " ", + debugstr_run( run ) ); }
para->nFlags |= MEPF_COMPLEX;
end: if (items != buf) heap_free( items ); + if (script_tags != tags) heap_free( script_tags ); return hr; }