/******************************************************************************
* ME_CanJoinRuns
*
- * Returns 1 if two runs can be safely merged into one, 0 otherwise.
- */
-int ME_CanJoinRuns(const ME_Run *run1, const ME_Run *run2)
+ * Returns TRUE if two runs can be safely merged into one, FALSE otherwise.
+ */
+BOOL ME_CanJoinRuns(const ME_Run *run1, const ME_Run *run2)
{
if ((run1->nFlags | run2->nFlags) & MERF_NOJOIN)
- return 0;
+ return FALSE;
if (run1->style != run2->style)
- return 0;
+ return FALSE;
if ((run1->nFlags & MERF_STYLEFLAGS) != (run2->nFlags & MERF_STYLEFLAGS))
- return 0;
- return 1;
+ return FALSE;
+ return TRUE;
}
void ME_SkipAndPropagateCharOffset(ME_DisplayItem *p, int shift)
item->member.run.nCharOfs = -1;
item->member.run.len = 0;
item->member.run.para = NULL;
+ item->member.run.num_glyphs = 0;
+ item->member.run.max_glyphs = 0;
+ item->member.run.glyphs = NULL;
+ item->member.run.vis_attrs = NULL;
+ item->member.run.advances = NULL;
+ item->member.run.offsets = NULL;
+ item->member.run.max_clusters = 0;
+ item->member.run.clusters = NULL;
ME_AddRefStyle(s);
return item;
}
ME_InsertRunAtCursor(ME_TextEditor *editor, ME_Cursor *cursor, ME_Style *style,
const WCHAR *str, int len, int flags)
{
- ME_DisplayItem *pDI;
+ ME_DisplayItem *pDI, *insert_before = cursor->pRun, *prev;
if (cursor->nOffset)
- ME_SplitRunSimple(editor, cursor);
+ {
+ if (cursor->nOffset == cursor->pRun->member.run.len)
+ {
+ insert_before = ME_FindItemFwd( cursor->pRun, diRun );
+ if (!insert_before) insert_before = cursor->pRun; /* Always insert before the final eop run */
+ }
+ else
+ {
+ ME_SplitRunSimple( editor, cursor );
+ insert_before = cursor->pRun;
+ }
+ }
- add_undo_delete_run( editor, cursor->pPara->member.para.nCharOfs +
- cursor->pRun->member.run.nCharOfs, len );
+ add_undo_delete_run( editor, insert_before->member.run.para->nCharOfs +
+ insert_before->member.run.nCharOfs, len );
pDI = ME_MakeRun(style, flags);
- pDI->member.run.nCharOfs = cursor->pRun->member.run.nCharOfs;
+ pDI->member.run.nCharOfs = insert_before->member.run.nCharOfs;
pDI->member.run.len = len;
- pDI->member.run.para = cursor->pRun->member.run.para;
+ pDI->member.run.para = insert_before->member.run.para;
ME_InsertString( pDI->member.run.para->text, pDI->member.run.nCharOfs, str, len );
- ME_InsertBefore(cursor->pRun, pDI);
+ ME_InsertBefore( insert_before, pDI );
TRACE("Shift length:%d\n", len);
- ME_PropagateCharOffset(cursor->pRun, len);
- cursor->pPara->member.para.nFlags |= MEPF_REWRAP;
+ ME_PropagateCharOffset( insert_before, len );
+ insert_before->member.run.para->nFlags |= MEPF_REWRAP;
+
+ /* Move any cursors that were at the end of the previous run to the end of the inserted run */
+ prev = ME_FindItemBack( pDI, diRun );
+ if (prev)
+ {
+ int i;
+
+ for (i = 0; i < editor->nCursors; i++)
+ {
+ if (editor->pCursors[i].pRun == prev &&
+ editor->pCursors[i].nOffset == prev->member.run.len)
+ {
+ editor->pCursors[i].pRun = pDI;
+ editor->pCursors[i].nOffset = len;
+ }
+ }
+ }
+
return pDI;
}
return 1;
}
+ if (run->para->nFlags & MEPF_COMPLEX)
+ {
+ int cp, trailing;
+ 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,
+ &cp, &trailing );
+ TRACE("x %d cp %d trailing %d (run width %d) rtl %d log order %d\n", cx, cp, trailing, run->nWidth,
+ run->script_analysis.fRTL, run->script_analysis.fLogicalOrder);
+ return closest ? cp + trailing : cp;
+ }
+
if (c->editor->cPasswordMask)
{
mask_text = ME_MakeStringR( c->editor->cPasswordMask, run->len );
nOffset = 0;
}
+ if (pRun->para->nFlags & MEPF_COMPLEX)
+ {
+ int x;
+ ScriptCPtoX( nOffset, FALSE, pRun->len, pRun->num_glyphs, pRun->clusters,
+ pRun->vis_attrs, pRun->advances, &pRun->script_analysis, &x );
+ if (visual_order && pRun->script_analysis.fRTL) x = pRun->nWidth - x - 1;
+ return x;
+ }
if (c->editor->cPasswordMask)
{
mask_text = ME_MakeStringR(c->editor->cPasswordMask, pRun->len);
* this is wasteful for MERF_NONTEXT runs, but that shouldn't matter
* in practice
*/
-
- if (c->editor->cPasswordMask)
+
+ if (para->nFlags & MEPF_COMPLEX)
+ {
+ size.cx = run->nWidth;
+ }
+ else if (c->editor->cPasswordMask)
{
ME_String *szMasked = ME_MakeStringR(c->editor->cPasswordMask,nLen);
ME_GetTextExtent(c, szMasked->szData, nLen,run->style, &size);
*/
void ME_SetCharFormat(ME_TextEditor *editor, ME_Cursor *start, ME_Cursor *end, CHARFORMAT2W *pFmt)
{
- ME_DisplayItem *para;
- ME_DisplayItem *run;
- ME_DisplayItem *end_run = NULL;
+ ME_DisplayItem *run, *start_run = start->pRun, *end_run = NULL;
if (end && start->pRun == end->pRun && start->nOffset == end->nOffset)
return;
- if (start->nOffset)
+ if (start->nOffset == start->pRun->member.run.len)
+ start_run = ME_FindItemFwd( start->pRun, diRun );
+ else if (start->nOffset)
{
/* SplitRunSimple may or may not update the cursors, depending on whether they
* are selection cursors, but we need to make sure they are valid. */
int split_offset = start->nOffset;
ME_DisplayItem *split_run = ME_SplitRunSimple(editor, start);
+ start_run = start->pRun;
if (end && end->pRun == split_run)
{
end->pRun = start->pRun;
}
}
- if (end && end->nOffset)
- ME_SplitRunSimple(editor, end);
- end_run = end ? end->pRun : NULL;
-
- run = start->pRun;
- para = start->pPara;
- para->member.para.nFlags |= MEPF_REWRAP;
+ if (end)
+ {
+ if (end->nOffset == end->pRun->member.run.len)
+ end_run = ME_FindItemFwd( end->pRun, diRun );
+ else
+ {
+ if (end->nOffset) ME_SplitRunSimple(editor, end);
+ end_run = end->pRun;
+ }
+ }
- while(run != end_run)
+ for (run = start_run; run != end_run; run = ME_FindItemFwd( run, diRun ))
{
ME_Style *new_style = ME_ApplyStyle(run->member.run.style, pFmt);
- /* ME_DumpStyle(new_style); */
- add_undo_set_char_fmt( editor, para->member.para.nCharOfs + run->member.run.nCharOfs,
+ add_undo_set_char_fmt( editor, run->member.run.para->nCharOfs + run->member.run.nCharOfs,
run->member.run.len, &run->member.run.style->fmt );
ME_ReleaseStyle(run->member.run.style);
run->member.run.style = new_style;
- run = ME_FindItemFwd(run, diRunOrParagraph);
- if (run && run->type == diParagraph)
- {
- para = run;
- run = ME_FindItemFwd(run, diRun);
- if (run != end_run)
- para->member.para.nFlags |= MEPF_REWRAP;
- }
+ run->member.run.para->nFlags |= MEPF_REWRAP;
}
}