return item;
}
-/******************************************************************************
- * ME_InsertRun
- *
- * Inserts a run at a given character position (offset).
- */
-ME_DisplayItem *ME_InsertRun(ME_TextEditor *editor, int nCharOfs, ME_DisplayItem *pItem)
-{
- ME_Cursor tmp;
- ME_DisplayItem *pDI;
-
- assert(pItem->type == diRun || pItem->type == diUndoInsertRun);
-
- ME_CursorFromCharOfs(editor, nCharOfs, &tmp);
- pDI = ME_InsertRunAtCursor(editor, &tmp, pItem->member.run.style,
- pItem->member.run.strText->szData,
- pItem->member.run.strText->nLen,
- pItem->member.run.nFlags);
-
- return pDI;
-}
-
/******************************************************************************
* ME_InsertRunAtCursor
*
static void ME_GetTextExtent(ME_Context *c, LPCWSTR szText, int nChars, ME_Style *s, SIZE *size)
{
HGDIOBJ hOldFont;
- hOldFont = ME_SelectStyleFont(c, s);
- GetTextExtentPoint32W(c->hDC, szText, nChars, size);
- ME_UnselectStyleFont(c, s, hOldFont);
+ if (c->hDC) {
+ hOldFont = ME_SelectStyleFont(c, s);
+ GetTextExtentPoint32W(c->hDC, szText, nChars, size);
+ ME_UnselectStyleFont(c, s, hOldFont);
+ } else {
+ size->cx = 0;
+ size->cy = 0;
+ }
}
/******************************************************************************
/******************************************************************************
* ME_SetSelectionCharFormat
- *
+ *
* Applies a style change, either to a current selection, or to insert cursor
* (ie. the style next typed characters will use).
- */
+ */
void ME_SetSelectionCharFormat(ME_TextEditor *editor, CHARFORMAT2W *pFmt)
{
- int nFrom, nTo;
- ME_GetSelection(editor, &nFrom, &nTo);
- if (nFrom == nTo)
+ if (!ME_IsSelection(editor))
{
ME_Style *s;
if (!editor->pBuffer->pCharStyle)
s = ME_ApplyStyle(editor->pBuffer->pCharStyle, pFmt);
ME_ReleaseStyle(editor->pBuffer->pCharStyle);
editor->pBuffer->pCharStyle = s;
+ } else {
+ ME_Cursor *from, *to;
+ ME_GetSelection(editor, &from, &to);
+ ME_SetCharFormat(editor, from, to, pFmt);
}
- else
- ME_SetCharFormat(editor, nFrom, nTo-nFrom, pFmt);
}
/******************************************************************************
* ME_SetCharFormat
- *
+ *
* Applies a style change to the specified part of the text
- */
-void ME_SetCharFormat(ME_TextEditor *editor, int nOfs, int nChars, CHARFORMAT2W *pFmt)
+ *
+ * The start and end cursors specify the part of the text. These cursors will
+ * be updated to stay valid, but this function may invalidate other
+ * non-selection cursors. The end cursor may be NULL to specify all the text
+ * following the start cursor.
+ *
+ * If no text is selected, then nothing is done.
+ */
+void ME_SetCharFormat(ME_TextEditor *editor, ME_Cursor *start, ME_Cursor *end, CHARFORMAT2W *pFmt)
{
- ME_Cursor tmp, tmp2;
ME_DisplayItem *para;
+ ME_DisplayItem *run;
+ ME_DisplayItem *end_run = NULL;
- ME_CursorFromCharOfs(editor, nOfs, &tmp);
- if (tmp.nOffset)
- tmp.pRun = ME_SplitRunSimple(editor, tmp.pRun, tmp.nOffset);
+ if (end && start->pRun == end->pRun && start->nOffset == end->nOffset)
+ return;
+
+ 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. */
+ ME_DisplayItem *split_run = start->pRun;
+ int split_offset = start->nOffset;
+ start->pRun = ME_SplitRunSimple(editor, split_run, split_offset);
+ start->nOffset = 0;
+ if (end && end->pRun == split_run)
+ {
+ end->pRun = start->pRun;
+ end->nOffset -= split_offset;
+ }
+ }
- ME_CursorFromCharOfs(editor, nOfs+nChars, &tmp2);
- if (tmp2.nOffset)
- tmp2.pRun = ME_SplitRunSimple(editor, tmp2.pRun, tmp2.nOffset);
+ if (end && end->nOffset)
+ {
+ end_run = end->pRun = ME_SplitRunSimple(editor, end->pRun, end->nOffset);
+ end->nOffset = 0;
+ } else if (end) {
+ end_run = end->pRun;
+ }
- para = tmp.pPara;
+ run = start->pRun;
+ para = start->pPara;
para->member.para.nFlags |= MEPF_REWRAP;
- while(tmp.pRun != tmp2.pRun)
+ while(run != end_run)
{
ME_UndoItem *undo = NULL;
- ME_Style *new_style = ME_ApplyStyle(tmp.pRun->member.run.style, pFmt);
+ ME_Style *new_style = ME_ApplyStyle(run->member.run.style, pFmt);
/* ME_DumpStyle(new_style); */
undo = ME_AddUndoItem(editor, diUndoSetCharFormat, NULL);
if (undo) {
- undo->nStart = tmp.pRun->member.run.nCharOfs+para->member.para.nCharOfs;
- undo->nLen = tmp.pRun->member.run.strText->nLen;
- undo->di.member.ustyle = tmp.pRun->member.run.style;
+ undo->nStart = run->member.run.nCharOfs+para->member.para.nCharOfs;
+ undo->nLen = run->member.run.strText->nLen;
+ undo->di.member.ustyle = run->member.run.style;
/* we'd have to addref undo...ustyle and release tmp...style
but they'd cancel each other out so we can do nothing instead */
}
else
- ME_ReleaseStyle(tmp.pRun->member.run.style);
- tmp.pRun->member.run.style = new_style;
- tmp.pRun = ME_FindItemFwd(tmp.pRun, diRunOrParagraph);
- if (tmp.pRun->type == diParagraph)
+ ME_ReleaseStyle(run->member.run.style);
+ run->member.run.style = new_style;
+ run = ME_FindItemFwd(run, diRunOrParagraph);
+ if (run && run->type == diParagraph)
{
- para = tmp.pRun;
- tmp.pRun = ME_FindItemFwd(tmp.pRun, diRun);
- if (tmp.pRun != tmp2.pRun)
+ para = run;
+ run = ME_FindItemFwd(run, diRun);
+ if (run != end_run)
para->member.para.nFlags |= MEPF_REWRAP;
}
- assert(tmp.pRun);
}
}
/******************************************************************************
* ME_GetSelectionCharFormat
- *
+ *
* If selection exists, it returns all style elements that are set consistently
- * in the whole selection. If not, it just returns the current style.
- */
+ * in the whole selection. If not, it just returns the current style.
+ */
void ME_GetSelectionCharFormat(ME_TextEditor *editor, CHARFORMAT2W *pFmt)
{
- int nFrom, nTo;
- ME_GetSelection(editor, &nFrom, &nTo);
- if (nFrom == nTo && editor->pBuffer->pCharStyle)
+ ME_Cursor *from, *to;
+ if (!ME_IsSelection(editor) && editor->pBuffer->pCharStyle)
{
ME_CopyCharFormat(pFmt, &editor->pBuffer->pCharStyle->fmt);
return;
}
- ME_GetCharFormat(editor, nFrom, nTo, pFmt);
+ ME_GetSelection(editor, &from, &to);
+ ME_GetCharFormat(editor, from, to, pFmt);
}
/******************************************************************************
* Returns the style consisting of those attributes which are consistently set
* in the whole character range.
*/
-void ME_GetCharFormat(ME_TextEditor *editor, int nFrom, int nTo, CHARFORMAT2W *pFmt)
+void ME_GetCharFormat(ME_TextEditor *editor, const ME_Cursor *from,
+ const ME_Cursor *to, CHARFORMAT2W *pFmt)
{
ME_DisplayItem *run, *run_end;
- int nOffset, nOffset2;
CHARFORMAT2W tmp;
- ME_RunOfsFromCharOfs(editor, nFrom, NULL, &run, &nOffset);
- if (nFrom == nTo) /* special case - if selection is empty, take previous char's formatting */
+ run = from->pRun;
+ /* special case - if selection is empty, take previous char's formatting */
+ if (from->pRun == to->pRun && from->nOffset == to->nOffset)
{
- if (!nOffset)
+ if (!from->nOffset)
{
ME_DisplayItem *tmp_run = ME_FindItemBack(run, diRunOrParagraph);
if (tmp_run->type == diRun) {
ME_GetRunCharFormat(editor, run, pFmt);
return;
}
-
- if (nTo>nFrom) /* selection consists of chars from nFrom up to nTo-1 */
- nTo--;
- ME_RunOfsFromCharOfs(editor, nTo, NULL, &run_end, &nOffset2);
+
+ run_end = to->pRun;
+ if (!to->nOffset)
+ run_end = ME_FindItemBack(run_end, diRun);
ME_GetRunCharFormat(editor, run, pFmt);