📄 run.c
字号:
* (nLen).
*/
static SIZE ME_GetRunSizeCommon(ME_Context *c, ME_Paragraph *para, ME_Run *run, int nLen,
int *pAscent, int *pDescent)
{
SIZE size;
int nMaxLen = ME_StrVLen(run->strText);
if (nLen>nMaxLen)
nLen = nMaxLen;
/* FIXME the following call also ensures that TEXTMETRIC structure is filled
* this is wasteful for MERF_NONTEXT runs, but that shouldn't matter
* in practice
*/
if (c->editor->cPasswordMask)
{
ME_String *szMasked = ME_MakeStringR(c->editor->cPasswordMask,nLen);
ME_GetTextExtent(c, szMasked->szData, nLen,run->style, &size);
ME_DestroyString(szMasked);
}
else
{
ME_GetTextExtent(c, run->strText->szData, nLen, run->style, &size);
}
*pAscent = run->style->tm.tmAscent;
*pDescent = run->style->tm.tmDescent;
size.cy = *pAscent + *pDescent;
if (run->nFlags & MERF_TAB)
{
int pos = 0, i = 0, ppos;
int lpsx = GetDeviceCaps(c->hDC, LOGPIXELSX);
PARAFORMAT2 *pFmt = para->pFmt;
do {
if (i < pFmt->cTabCount)
{
pos = pFmt->rgxTabs[i]&0x00FFFFFF;
i++;
}
else
{
pos += 720-(pos%720);
}
ppos = pos*lpsx/1440;
if (ppos>run->pt.x) {
size.cx = ppos - run->pt.x;
break;
}
} while(1);
size.cy = *pAscent + *pDescent;
return size;
}
if (run->nFlags & MERF_GRAPHICS)
{
ME_GetGraphicsSize(c->editor, run, &size);
if (size.cy > *pAscent)
*pAscent = size.cy;
/* descent is unchanged */
return size;
}
if (run->nFlags & MERF_CELL)
{
int lpsx = GetDeviceCaps(c->hDC, LOGPIXELSX);
size.cx = run->pCell->nRightBoundary * lpsx / 1440 - run->pt.x;
return size;
}
return size;
}
/******************************************************************************
* ME_GetRunSize
*
* Finds width and height (but not ascent and descent) of a part of the run
* up to given character.
*/
SIZE ME_GetRunSize(ME_Context *c, ME_Paragraph *para, ME_Run *run, int nLen)
{
int asc, desc;
return ME_GetRunSizeCommon(c, para, run, nLen, &asc, &desc);
}
/******************************************************************************
* ME_CalcRunExtent
*
* Updates the size of the run (fills width, ascent and descent). The height
* is calculated based on whole row's ascent and descent anyway, so no need
* to use it here.
*/
void ME_CalcRunExtent(ME_Context *c, ME_Paragraph *para, ME_Run *run)
{
if (run->nFlags & MERF_HIDDEN)
run->nWidth = 0;
else
{
int nEnd = ME_StrVLen(run->strText);
SIZE size = ME_GetRunSizeCommon(c, para, run, nEnd, &run->nAscent, &run->nDescent);
run->nWidth = size.cx;
if (!size.cx)
WARN("size.cx == 0\n");
}
}
/******************************************************************************
* ME_MustBeWrapped
*
* This should ensure that the given paragraph is wrapped so that its screen
* row structure may be used. But it doesn't, yet.
*/
void ME_MustBeWrapped(ME_Context *c, ME_DisplayItem *para)
{
assert(para->type == diParagraph);
/* FIXME */
}
/******************************************************************************
* 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)
{
ME_Style *s;
if (!editor->pBuffer->pCharStyle)
editor->pBuffer->pCharStyle = ME_GetInsertStyle(editor, 0);
s = ME_ApplyStyle(editor->pBuffer->pCharStyle, pFmt);
ME_ReleaseStyle(editor->pBuffer->pCharStyle);
editor->pBuffer->pCharStyle = s;
}
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)
{
ME_Cursor tmp, tmp2;
ME_DisplayItem *para;
ME_CursorFromCharOfs(editor, nOfs, &tmp);
if (tmp.nOffset)
tmp.pRun = ME_SplitRunSimple(editor, tmp.pRun, tmp.nOffset);
ME_CursorFromCharOfs(editor, nOfs+nChars, &tmp2);
if (tmp2.nOffset)
tmp2.pRun = ME_SplitRunSimple(editor, tmp2.pRun, tmp2.nOffset);
para = ME_GetParagraph(tmp.pRun);
para->member.para.nFlags |= MEPF_REWRAP;
while(tmp.pRun != tmp2.pRun)
{
ME_UndoItem *undo = NULL;
ME_Style *new_style = ME_ApplyStyle(tmp.pRun->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;
/* 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)
{
para = tmp.pRun;
tmp.pRun = ME_FindItemFwd(tmp.pRun, diRun);
if (tmp.pRun != tmp2.pRun)
para->member.para.nFlags |= MEPF_REWRAP;
}
assert(tmp.pRun);
}
}
/******************************************************************************
* ME_SetDefaultCharFormat
*
* Applies a style change to the default character style.
*/
void ME_SetDefaultCharFormat(ME_TextEditor *editor, CHARFORMAT2W *mod)
{
ME_Style *style;
ME_UndoItem *undo;
assert(mod->cbSize == sizeof(CHARFORMAT2W));
undo = ME_AddUndoItem(editor, diUndoSetDefaultCharFormat, NULL);
if (undo) {
undo->nStart = -1;
undo->nLen = -1;
undo->di.member.ustyle = editor->pBuffer->pDefaultStyle;
ME_AddRefStyle(undo->di.member.ustyle);
}
style = ME_ApplyStyle(editor->pBuffer->pDefaultStyle, mod);
editor->pBuffer->pDefaultStyle->fmt = style->fmt;
editor->pBuffer->pDefaultStyle->tm = style->tm;
ME_ReleaseStyle(style);
ME_MarkAllForWrapping(editor);
/* pcf = editor->pBuffer->pDefaultStyle->fmt; */
}
static void ME_GetRunCharFormat(ME_TextEditor *editor, ME_DisplayItem *run, CHARFORMAT2W *pFmt)
{
ME_CopyCharFormat(pFmt, &run->member.run.style->fmt);
}
/******************************************************************************
* ME_GetDefaultCharFormat
*
* Retrieves the current default character style (the one applied where no
* other style was applied) .
*/
void ME_GetDefaultCharFormat(ME_TextEditor *editor, CHARFORMAT2W *pFmt)
{
int nFrom, nTo;
ME_GetSelection(editor, &nFrom, &nTo);
ME_CopyCharFormat(pFmt, &editor->pBuffer->pDefaultStyle->fmt);
}
/******************************************************************************
* 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.
*/
void ME_GetSelectionCharFormat(ME_TextEditor *editor, CHARFORMAT2W *pFmt)
{
int nFrom, nTo;
ME_GetSelection(editor, &nFrom, &nTo);
if (nFrom == nTo && editor->pBuffer->pCharStyle)
{
ME_CopyCharFormat(pFmt, &editor->pBuffer->pCharStyle->fmt);
return;
}
ME_GetCharFormat(editor, nFrom, nTo, pFmt);
}
/******************************************************************************
* ME_GetCharFormat
*
* 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)
{
ME_DisplayItem *run, *run_end;
int nOffset, nOffset2;
CHARFORMAT2W tmp;
ME_RunOfsFromCharOfs(editor, nFrom, &run, &nOffset);
if (nFrom == nTo) /* special case - if selection is empty, take previous char's formatting */
{
if (!nOffset)
{
ME_DisplayItem *tmp_run = ME_FindItemBack(run, diRunOrParagraph);
if (tmp_run->type == diRun) {
ME_GetRunCharFormat(editor, tmp_run, pFmt);
return;
}
}
ME_GetRunCharFormat(editor, run, pFmt);
return;
}
if (nTo>nFrom) /* selection consists of chars from nFrom up to nTo-1 */
nTo--;
ME_RunOfsFromCharOfs(editor, nTo, &run_end, &nOffset2);
ME_GetRunCharFormat(editor, run, pFmt);
if (run == run_end) return;
do {
/* FIXME add more style feature comparisons */
int nAttribs = CFM_SIZE | CFM_FACE | CFM_COLOR;
int nEffects = CFM_BOLD | CFM_ITALIC | CFM_UNDERLINE;
run = ME_FindItemFwd(run, diRun);
ZeroMemory(&tmp, sizeof(tmp));
tmp.cbSize = sizeof(tmp);
ME_GetRunCharFormat(editor, run, &tmp);
assert((tmp.dwMask & nAttribs) == nAttribs);
assert((tmp.dwMask & nEffects) == nEffects);
/* reset flags that differ */
if (pFmt->yHeight != tmp.yHeight)
pFmt->dwMask &= ~CFM_SIZE;
if (pFmt->dwMask & CFM_FACE)
{
if (!(tmp.dwMask & CFM_FACE))
pFmt->dwMask &= ~CFM_FACE;
else if (lstrcmpW(pFmt->szFaceName, tmp.szFaceName))
pFmt->dwMask &= ~CFM_FACE;
}
if (pFmt->yHeight != tmp.yHeight)
pFmt->dwMask &= ~CFM_SIZE;
if (pFmt->dwMask & CFM_COLOR)
{
if (!((pFmt->dwEffects&CFE_AUTOCOLOR) & (tmp.dwEffects&CFE_AUTOCOLOR)))
{
if (pFmt->crTextColor != tmp.crTextColor)
pFmt->dwMask &= ~CFM_COLOR;
}
}
pFmt->dwMask &= ~((pFmt->dwEffects ^ tmp.dwEffects) & nEffects);
} while(run != run_end);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -