+static HRESULT itemize_para( ME_Context *c, ME_DisplayItem *p )
+{
+ ME_Paragraph *para = &p->member.para;
+ ME_Run *run;
+ ME_DisplayItem *di;
+ SCRIPT_ITEM buf[16], *items = buf;
+ int items_passed = sizeof( buf ) / sizeof( buf[0] ), num_items, cur_item;
+ SCRIPT_CONTROL control = { LANG_USER_DEFAULT, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE,
+ FALSE, FALSE, 0 };
+ SCRIPT_STATE state = { 0, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, 0, 0 };
+ HRESULT hr;
+
+ assert( p->type == diParagraph );
+
+ while (1)
+ {
+ hr = ScriptItemize( para->text->szData, para->text->nLen, items_passed, &control,
+ &state, items, &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 ) );
+ else
+ items = heap_realloc( items, items_passed * sizeof( *items ) );
+ if (!items) break;
+ }
+ if (FAILED( hr )) goto end;
+
+ if (TRACE_ON( richedit ))
+ {
+ TRACE( "got items:\n" );
+ for (cur_item = 0; cur_item < num_items; cur_item++)
+ {
+ TRACE( "\t%d - %d RTL %d bidi level %d\n", items[cur_item].iCharPos, items[cur_item+1].iCharPos - 1,
+ items[cur_item].a.fRTL, items[cur_item].a.s.uBidiLevel );
+ }
+
+ TRACE( "before splitting runs into ranges\n" );
+ for (di = p->next; di != p->member.para.next_para; di = di->next)
+ {
+ if (di->type != diRun) continue;
+ TRACE( "\t%d: %s\n", di->member.run.nCharOfs, debugstr_run( &di->member.run ) );
+ }
+ }
+
+ /* split runs into ranges at item boundaries */
+ for (di = p->next, cur_item = 0; di != p->member.para.next_para; di = di->next)
+ {
+ if (di->type != diRun) continue;
+ run = &di->member.run;
+
+ if (run->nCharOfs == items[cur_item+1].iCharPos) cur_item++;
+
+ items[cur_item].a.fLogicalOrder = TRUE;
+ run->script_analysis = items[cur_item].a;
+
+ if (run->nFlags & MERF_ENDPARA) break; /* don't split eop runs */
+
+ if (run->nCharOfs + run->len > items[cur_item+1].iCharPos)
+ {
+ ME_Cursor cursor = {p, di, items[cur_item+1].iCharPos - run->nCharOfs};
+ ME_SplitRunSimple( c->editor, &cursor );
+ }
+ }
+
+ if (TRACE_ON( richedit ))
+ {
+ TRACE( "after splitting into ranges\n" );
+ for (di = p->next; di != p->member.para.next_para; di = di->next)
+ {
+ if (di->type != diRun) continue;
+ TRACE( "\t%d: %s\n", di->member.run.nCharOfs, debugstr_run( &di->member.run ) );
+ }
+ }
+
+ para->nFlags |= MEPF_COMPLEX;
+
+end:
+ if (items != buf) heap_free( items );
+ return hr;
+}
+
+
+static HRESULT shape_para( ME_Context *c, ME_DisplayItem *p )
+{
+ ME_DisplayItem *di;
+ ME_Run *run;
+ HRESULT hr;
+
+ for (di = p->next; di != p->member.para.next_para; di = di->next)
+ {
+ if (di->type != diRun) continue;
+ run = &di->member.run;
+
+ hr = shape_run( c, run );
+ if (FAILED( hr ))
+ {
+ run->para->nFlags &= ~MEPF_COMPLEX;
+ return hr;
+ }
+ }
+ return hr;
+}
+