Huw Davies (@huw) commented about dlls/riched20/run.c:
if (run->para->nFlags & MEPF_COMPLEX) {
int cp, trailing;
SCRIPT_VISATTR *script_visattrs;
int cp, trailing, i; if (visual_order && run->script_analysis.fRTL) cx = run->nWidth - cx - 1;
ScriptXtoCP( cx, run->len, run->num_glyphs, run->clusters, run->vis_attrs, run->advances, &run->script_analysis,
script_visattrs = heap_alloc( run->num_glyphs * sizeof(SCRIPT_VISATTR) );
for (i = 0; i < run->num_glyphs; i++)
script_visattrs[i] = run->glyph_props[i].sva;
ScriptXtoCP( cx, run->len, run->num_glyphs, run->clusters, script_visattrs, run->advances, &run->script_analysis, &cp, &trailing );
heap_free( script_visattrs );
Ah right, this copying is unfortunate. Let's stick with keeping the vis_attrs in the run and allocate temporary glyph_props when calling `ScriptShapeOpenType()` which are then used to initialize the run's vis_attrs.