riched20: Fix the interaction between CFE_UNDERLINE and bUnderlineType.
The effect specifies whether underlining is turned on, while bUnderlineType indicates the type of underlining. Signed-off-by: Huw Davies <huw@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
3ac78b763b
commit
aa57db38dd
|
@ -427,11 +427,12 @@ void ME_RTFCharAttrHook(RTF_Info *info)
|
|||
{
|
||||
case rtfPlain:
|
||||
/* FIXME add more flags once they're implemented */
|
||||
fmt.dwMask = CFM_BOLD | CFM_ITALIC | CFM_UNDERLINETYPE | CFM_STRIKEOUT | CFM_COLOR | CFM_BACKCOLOR | CFM_SIZE | CFM_WEIGHT;
|
||||
fmt.dwMask = CFM_BOLD | CFM_ITALIC | CFM_UNDERLINE | CFM_UNDERLINETYPE | CFM_STRIKEOUT |
|
||||
CFM_COLOR | CFM_BACKCOLOR | CFM_SIZE | CFM_WEIGHT;
|
||||
fmt.dwEffects = CFE_AUTOCOLOR | CFE_AUTOBACKCOLOR;
|
||||
fmt.yHeight = 12*20; /* 12pt */
|
||||
fmt.wWeight = FW_NORMAL;
|
||||
fmt.bUnderlineType = CFU_UNDERLINENONE;
|
||||
fmt.bUnderlineType = CFU_UNDERLINE;
|
||||
break;
|
||||
case rtfBold:
|
||||
fmt.dwMask = CFM_BOLD | CFM_WEIGHT;
|
||||
|
@ -443,24 +444,28 @@ void ME_RTFCharAttrHook(RTF_Info *info)
|
|||
fmt.dwEffects = info->rtfParam ? fmt.dwMask : 0;
|
||||
break;
|
||||
case rtfUnderline:
|
||||
fmt.dwMask = CFM_UNDERLINETYPE;
|
||||
fmt.bUnderlineType = info->rtfParam ? CFU_CF1UNDERLINE : CFU_UNDERLINENONE;
|
||||
fmt.dwMask = CFM_UNDERLINETYPE | CFM_UNDERLINE;
|
||||
fmt.bUnderlineType = CFU_UNDERLINE;
|
||||
fmt.dwEffects = info->rtfParam ? CFE_UNDERLINE : 0;
|
||||
break;
|
||||
case rtfDotUnderline:
|
||||
fmt.dwMask = CFM_UNDERLINETYPE;
|
||||
fmt.bUnderlineType = info->rtfParam ? CFU_UNDERLINEDOTTED : CFU_UNDERLINENONE;
|
||||
fmt.dwMask = CFM_UNDERLINETYPE | CFM_UNDERLINE;
|
||||
fmt.bUnderlineType = CFU_UNDERLINEDOTTED;
|
||||
fmt.dwEffects = info->rtfParam ? CFE_UNDERLINE : 0;
|
||||
break;
|
||||
case rtfDbUnderline:
|
||||
fmt.dwMask = CFM_UNDERLINETYPE;
|
||||
fmt.bUnderlineType = info->rtfParam ? CFU_UNDERLINEDOUBLE : CFU_UNDERLINENONE;
|
||||
fmt.dwMask = CFM_UNDERLINETYPE | CFM_UNDERLINE;
|
||||
fmt.bUnderlineType = CFU_UNDERLINEDOUBLE;
|
||||
fmt.dwEffects = info->rtfParam ? CFE_UNDERLINE : 0;
|
||||
break;
|
||||
case rtfWordUnderline:
|
||||
fmt.dwMask = CFM_UNDERLINETYPE;
|
||||
fmt.bUnderlineType = info->rtfParam ? CFU_UNDERLINEWORD : CFU_UNDERLINENONE;
|
||||
fmt.dwMask = CFM_UNDERLINETYPE | CFM_UNDERLINE;
|
||||
fmt.bUnderlineType = CFU_UNDERLINEWORD;
|
||||
fmt.dwEffects = info->rtfParam ? CFE_UNDERLINE : 0;
|
||||
break;
|
||||
case rtfNoUnderline:
|
||||
fmt.dwMask = CFM_UNDERLINETYPE;
|
||||
fmt.bUnderlineType = CFU_UNDERLINENONE;
|
||||
fmt.dwMask = CFM_UNDERLINE;
|
||||
fmt.dwEffects = 0;
|
||||
break;
|
||||
case rtfStrikeThru:
|
||||
fmt.dwMask = CFM_STRIKEOUT;
|
||||
|
|
|
@ -220,7 +220,7 @@ static void get_underline_pen( ME_Style *style, COLORREF color, HPEN *pen )
|
|||
{
|
||||
*pen = NULL;
|
||||
/* Choose the pen type for underlining the text. */
|
||||
if (style->fmt.dwMask & CFM_UNDERLINETYPE)
|
||||
if (style->fmt.dwEffects & CFE_UNDERLINE)
|
||||
{
|
||||
switch (style->fmt.bUnderlineType)
|
||||
{
|
||||
|
|
|
@ -66,7 +66,8 @@ void ME_MakeFirstParagraph(ME_TextEditor *editor)
|
|||
if (lf.lfWeight > FW_NORMAL) cf.dwEffects |= CFE_BOLD;
|
||||
cf.wWeight = lf.lfWeight;
|
||||
if (lf.lfItalic) cf.dwEffects |= CFE_ITALIC;
|
||||
cf.bUnderlineType = (lf.lfUnderline) ? CFU_CF1UNDERLINE : CFU_UNDERLINENONE;
|
||||
if (lf.lfUnderline) cf.dwEffects |= CFE_UNDERLINE;
|
||||
cf.bUnderlineType = CFU_UNDERLINE;
|
||||
if (lf.lfStrikeOut) cf.dwEffects |= CFE_STRIKEOUT;
|
||||
cf.bPitchAndFamily = lf.lfPitchAndFamily;
|
||||
cf.bCharSet = lf.lfCharSet;
|
||||
|
|
|
@ -773,16 +773,6 @@ void ME_SetCharFormat(ME_TextEditor *editor, ME_Cursor *start, ME_Cursor *end, C
|
|||
static void ME_GetRunCharFormat(ME_TextEditor *editor, ME_DisplayItem *run, CHARFORMAT2W *pFmt)
|
||||
{
|
||||
ME_CopyCharFormat(pFmt, &run->member.run.style->fmt);
|
||||
if ((pFmt->dwMask & CFM_UNDERLINETYPE) && (pFmt->bUnderlineType == CFU_CF1UNDERLINE))
|
||||
{
|
||||
pFmt->dwMask |= CFM_UNDERLINE;
|
||||
pFmt->dwEffects |= CFE_UNDERLINE;
|
||||
}
|
||||
if ((pFmt->dwMask & CFM_UNDERLINETYPE) && (pFmt->bUnderlineType == CFU_UNDERLINENONE))
|
||||
{
|
||||
pFmt->dwMask |= CFM_UNDERLINE;
|
||||
pFmt->dwEffects &= ~CFE_UNDERLINE;
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
|
|
|
@ -79,20 +79,6 @@ static CHARFORMAT2W *ME_ToCFAny(CHARFORMAT2W *to, CHARFORMAT2W *from)
|
|||
CHARFORMATA *t = (CHARFORMATA *)to;
|
||||
CopyMemory(t, from, FIELD_OFFSET(CHARFORMATA, szFaceName));
|
||||
WideCharToMultiByte(CP_ACP, 0, from->szFaceName, -1, t->szFaceName, sizeof(t->szFaceName), NULL, NULL);
|
||||
if (from->dwMask & CFM_UNDERLINETYPE)
|
||||
{
|
||||
switch (from->bUnderlineType)
|
||||
{
|
||||
case CFU_CF1UNDERLINE:
|
||||
to->dwMask |= CFM_UNDERLINE;
|
||||
to->dwEffects |= CFE_UNDERLINE;
|
||||
break;
|
||||
case CFU_UNDERLINENONE:
|
||||
to->dwMask |= CFM_UNDERLINE;
|
||||
to->dwEffects &= ~CFE_UNDERLINE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
t->cbSize = sizeof(*t); /* it was overwritten by CopyMemory */
|
||||
return to;
|
||||
}
|
||||
|
@ -100,20 +86,6 @@ static CHARFORMAT2W *ME_ToCFAny(CHARFORMAT2W *to, CHARFORMAT2W *from)
|
|||
{
|
||||
CHARFORMATW *t = (CHARFORMATW *)to;
|
||||
CopyMemory(t, from, sizeof(*t));
|
||||
if (from->dwMask & CFM_UNDERLINETYPE)
|
||||
{
|
||||
switch (from->bUnderlineType)
|
||||
{
|
||||
case CFU_CF1UNDERLINE:
|
||||
to->dwMask |= CFM_UNDERLINE;
|
||||
to->dwEffects |= CFE_UNDERLINE;
|
||||
break;
|
||||
case CFU_UNDERLINENONE:
|
||||
to->dwMask |= CFM_UNDERLINE;
|
||||
to->dwEffects &= ~CFE_UNDERLINE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
t->cbSize = sizeof(*t); /* it was overwritten by CopyMemory */
|
||||
return to;
|
||||
}
|
||||
|
@ -195,7 +167,6 @@ ME_Style *ME_ApplyStyle(ME_TextEditor *editor, ME_Style *sSrc, CHARFORMAT2W *mod
|
|||
}
|
||||
COPY_STYLE_ITEM(CFM_SPACING, sSpacing);
|
||||
COPY_STYLE_ITEM(CFM_STYLE, sStyle);
|
||||
COPY_STYLE_ITEM(CFM_UNDERLINETYPE, bUnderlineType);
|
||||
COPY_STYLE_ITEM(CFM_WEIGHT, wWeight);
|
||||
/* FIXME: this is not documented this way, but that's the more logical */
|
||||
COPY_STYLE_ITEM(CFM_FACE, bPitchAndFamily);
|
||||
|
@ -210,12 +181,18 @@ ME_Style *ME_ApplyStyle(ME_TextEditor *editor, ME_Style *sSrc, CHARFORMAT2W *mod
|
|||
else
|
||||
fmt.dwEffects &= ~CFE_AUTOCOLOR;
|
||||
}
|
||||
if (mod->dwMask & CFM_UNDERLINE)
|
||||
|
||||
COPY_STYLE_ITEM(CFM_UNDERLINETYPE, bUnderlineType);
|
||||
/* If the CFM_UNDERLINE effect is not specified set it appropiately */
|
||||
if ((mod->dwMask & CFM_UNDERLINETYPE) && !(mod->dwMask & CFM_UNDERLINE))
|
||||
{
|
||||
fmt.dwMask |= CFM_UNDERLINETYPE;
|
||||
fmt.bUnderlineType = (mod->dwEffects & CFM_UNDERLINE) ?
|
||||
CFU_CF1UNDERLINE : CFU_UNDERLINENONE;
|
||||
fmt.dwMask |= CFM_UNDERLINE;
|
||||
if (mod->bUnderlineType == CFU_UNDERLINENONE)
|
||||
fmt.dwEffects &= ~CFE_UNDERLINE;
|
||||
else
|
||||
fmt.dwEffects |= CFE_UNDERLINE;
|
||||
}
|
||||
|
||||
if (mod->dwMask & CFM_BOLD && !(mod->dwMask & CFM_WEIGHT))
|
||||
{
|
||||
fmt.wWeight = (mod->dwEffects & CFE_BOLD) ? FW_BOLD : FW_NORMAL;
|
||||
|
@ -329,9 +306,8 @@ ME_LogFontFromStyle(ME_Context* c, LOGFONTW *lf, const ME_Style *s)
|
|||
lf->lfWeight = s->fmt.wWeight;
|
||||
if (s->fmt.dwEffects & s->fmt.dwMask & CFM_ITALIC)
|
||||
lf->lfItalic = 1;
|
||||
if (s->fmt.dwEffects & s->fmt.dwMask & (CFM_UNDERLINE | CFE_LINK))
|
||||
lf->lfUnderline = 1;
|
||||
if (s->fmt.dwMask & CFM_UNDERLINETYPE && s->fmt.bUnderlineType == CFU_CF1UNDERLINE)
|
||||
if ((s->fmt.dwEffects & s->fmt.dwMask & (CFM_UNDERLINE | CFE_LINK)) &&
|
||||
s->fmt.bUnderlineType == CFU_CF1UNDERLINE)
|
||||
lf->lfUnderline = 1;
|
||||
if (s->fmt.dwEffects & s->fmt.dwMask & CFM_STRIKEOUT)
|
||||
lf->lfStrikeOut = 1;
|
||||
|
@ -352,14 +328,13 @@ void ME_CharFormatFromLogFont(HDC hDC, const LOGFONTW *lf, CHARFORMAT2W *fmt)
|
|||
ry = GetDeviceCaps(hDC, LOGPIXELSY);
|
||||
lstrcpyW(fmt->szFaceName, lf->lfFaceName);
|
||||
fmt->dwEffects = 0;
|
||||
fmt->dwMask = CFM_WEIGHT|CFM_BOLD|CFM_ITALIC|CFM_UNDERLINE|CFM_STRIKEOUT|CFM_SIZE|CFM_FACE|CFM_CHARSET;
|
||||
fmt->dwMask = CFM_WEIGHT|CFM_BOLD|CFM_ITALIC|CFM_UNDERLINE|CFM_UNDERLINETYPE|CFM_STRIKEOUT|CFM_SIZE|CFM_FACE|CFM_CHARSET;
|
||||
fmt->wWeight = lf->lfWeight;
|
||||
fmt->yHeight = -lf->lfHeight*1440/ry;
|
||||
if (lf->lfWeight > FW_NORMAL) fmt->dwEffects |= CFM_BOLD;
|
||||
if (lf->lfItalic) fmt->dwEffects |= CFM_ITALIC;
|
||||
if (lf->lfUnderline) fmt->dwEffects |= CFM_UNDERLINE;
|
||||
/* notice that if a logfont was created with underline due to CFM_LINK, this
|
||||
would add an erroneous CFM_UNDERLINE. This isn't currently ever a problem. */
|
||||
fmt->bUnderlineType = CFU_UNDERLINE;
|
||||
if (lf->lfStrikeOut) fmt->dwEffects |= CFM_STRIKEOUT;
|
||||
fmt->bPitchAndFamily = lf->lfPitchAndFamily;
|
||||
fmt->bCharSet = lf->lfCharSet;
|
||||
|
|
|
@ -1256,6 +1256,85 @@ static void test_EM_SETCHARFORMAT(void)
|
|||
SendMessageA(hwndRichEdit, EM_GETCHARFORMAT, SCF_SELECTION, (LPARAM)&cfW);
|
||||
ok(cfW.sSpacing == 10, "got %d\n", cfW.sSpacing);
|
||||
|
||||
/* test CFE_UNDERLINE and bUnderlineType interaction */
|
||||
/* clear bold, italic */
|
||||
SendMessageA(hwndRichEdit, EM_SETSEL, 0, -1);
|
||||
memset(&cf2, 0, sizeof(CHARFORMAT2A));
|
||||
cf2.cbSize = sizeof(CHARFORMAT2A);
|
||||
cf2.dwMask = CFM_BOLD | CFM_ITALIC;
|
||||
cf2.dwEffects = 0;
|
||||
SendMessageA(hwndRichEdit, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf2);
|
||||
|
||||
/* check CFE_UNDERLINE is clear and bUnderlineType is CFU_UNDERLINE */
|
||||
memset(&cf2, 0, sizeof(CHARFORMAT2A));
|
||||
cf2.cbSize = sizeof(CHARFORMAT2A);
|
||||
SendMessageA(hwndRichEdit, EM_GETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf2);
|
||||
ok((cf2.dwMask & (CFM_UNDERLINE | CFM_UNDERLINETYPE)) == (CFM_UNDERLINE | CFM_UNDERLINETYPE),
|
||||
"got %08x\n", cf2.dwMask);
|
||||
ok(!(cf2.dwEffects & CFE_UNDERLINE), "got %08x\n", cf2.dwEffects);
|
||||
ok(cf2.bUnderlineType == CFU_UNDERLINE, "got %x\n", cf2.bUnderlineType);
|
||||
|
||||
/* simply touching bUnderlineType will toggle CFE_UNDERLINE */
|
||||
cf2.dwMask = CFM_UNDERLINETYPE;
|
||||
cf2.bUnderlineType = CFU_UNDERLINE;
|
||||
SendMessageA(hwndRichEdit, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf2);
|
||||
memset(&cf2, 0, sizeof(CHARFORMAT2A));
|
||||
cf2.cbSize = sizeof(CHARFORMAT2A);
|
||||
SendMessageA(hwndRichEdit, EM_GETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf2);
|
||||
ok((cf2.dwMask & (CFM_UNDERLINE | CFM_UNDERLINETYPE)) == (CFM_UNDERLINE | CFM_UNDERLINETYPE),
|
||||
"got %08x\n", cf2.dwMask);
|
||||
ok(cf2.dwEffects & CFE_UNDERLINE, "got %08x\n", cf2.dwEffects);
|
||||
ok(cf2.bUnderlineType == CFU_UNDERLINE, "got %x\n", cf2.bUnderlineType);
|
||||
|
||||
/* setting bUnderline to CFU_UNDERLINENONE clears CFE_UNDERLINE */
|
||||
cf2.dwMask = CFM_UNDERLINETYPE;
|
||||
cf2.bUnderlineType = CFU_UNDERLINENONE;
|
||||
SendMessageA(hwndRichEdit, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf2);
|
||||
memset(&cf2, 0, sizeof(CHARFORMAT2A));
|
||||
cf2.cbSize = sizeof(CHARFORMAT2A);
|
||||
SendMessageA(hwndRichEdit, EM_GETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf2);
|
||||
ok((cf2.dwMask & (CFM_UNDERLINE | CFM_UNDERLINETYPE)) == (CFM_UNDERLINE | CFM_UNDERLINETYPE),
|
||||
"got %08x\n", cf2.dwMask);
|
||||
ok(!(cf2.dwEffects & CFE_UNDERLINE), "got %08x\n", cf2.dwEffects);
|
||||
ok(cf2.bUnderlineType == CFU_UNDERLINENONE, "got %x\n", cf2.bUnderlineType);
|
||||
|
||||
/* another underline type also sets CFE_UNDERLINE */
|
||||
cf2.dwMask = CFM_UNDERLINETYPE;
|
||||
cf2.bUnderlineType = CFU_UNDERLINEDOUBLE;
|
||||
SendMessageA(hwndRichEdit, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf2);
|
||||
memset(&cf2, 0, sizeof(CHARFORMAT2A));
|
||||
cf2.cbSize = sizeof(CHARFORMAT2A);
|
||||
SendMessageA(hwndRichEdit, EM_GETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf2);
|
||||
ok((cf2.dwMask & (CFM_UNDERLINE | CFM_UNDERLINETYPE)) == (CFM_UNDERLINE | CFM_UNDERLINETYPE),
|
||||
"got %08x\n", cf2.dwMask);
|
||||
ok(cf2.dwEffects & CFE_UNDERLINE, "got %08x\n", cf2.dwEffects);
|
||||
ok(cf2.bUnderlineType == CFU_UNDERLINEDOUBLE, "got %x\n", cf2.bUnderlineType);
|
||||
|
||||
/* However explicitly clearing CFE_UNDERLINE results in it remaining cleared */
|
||||
cf2.dwMask = CFM_UNDERLINETYPE | CFM_UNDERLINE;
|
||||
cf2.bUnderlineType = CFU_UNDERLINEDOUBLE;
|
||||
cf2.dwEffects = 0;
|
||||
SendMessageA(hwndRichEdit, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf2);
|
||||
memset(&cf2, 0, sizeof(CHARFORMAT2A));
|
||||
cf2.cbSize = sizeof(CHARFORMAT2A);
|
||||
SendMessageA(hwndRichEdit, EM_GETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf2);
|
||||
ok((cf2.dwMask & (CFM_UNDERLINE | CFM_UNDERLINETYPE)) == (CFM_UNDERLINE | CFM_UNDERLINETYPE),
|
||||
"got %08x\n", cf2.dwMask);
|
||||
ok(!(cf2.dwEffects & CFE_UNDERLINE), "got %08x\n", cf2.dwEffects);
|
||||
ok(cf2.bUnderlineType == CFU_UNDERLINEDOUBLE, "got %x\n", cf2.bUnderlineType);
|
||||
|
||||
/* And turing it back on again by just setting CFE_UNDERLINE */
|
||||
cf2.dwMask = CFM_UNDERLINE;
|
||||
cf2.dwEffects = CFE_UNDERLINE;
|
||||
SendMessageA(hwndRichEdit, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf2);
|
||||
memset(&cf2, 0, sizeof(CHARFORMAT2A));
|
||||
cf2.cbSize = sizeof(CHARFORMAT2A);
|
||||
SendMessageA(hwndRichEdit, EM_GETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf2);
|
||||
ok((cf2.dwMask & (CFM_UNDERLINE | CFM_UNDERLINETYPE)) == (CFM_UNDERLINE | CFM_UNDERLINETYPE),
|
||||
"got %08x\n", cf2.dwMask);
|
||||
ok(cf2.dwEffects & CFE_UNDERLINE, "got %08x\n", cf2.dwEffects);
|
||||
ok(cf2.bUnderlineType == CFU_UNDERLINEDOUBLE, "got %x\n", cf2.bUnderlineType);
|
||||
|
||||
DestroyWindow(hwndRichEdit);
|
||||
}
|
||||
|
||||
|
|
|
@ -787,29 +787,28 @@ ME_StreamOutRTFCharProps(ME_OutStream *pStream, CHARFORMAT2W *fmt)
|
|||
else if (fmt->dwEffects & CFE_SUPERSCRIPT)
|
||||
strcat(props, "\\super");
|
||||
}
|
||||
if (fmt->dwMask & CFM_UNDERLINE || fmt->dwMask & CFM_UNDERLINETYPE) {
|
||||
if (fmt->dwMask & CFM_UNDERLINETYPE)
|
||||
switch (fmt->bUnderlineType) {
|
||||
case CFU_CF1UNDERLINE:
|
||||
case CFU_UNDERLINE:
|
||||
if (fmt->dwEffects & CFE_UNDERLINE)
|
||||
{
|
||||
switch (fmt->bUnderlineType)
|
||||
{
|
||||
case CFU_UNDERLINE:
|
||||
strcat(props, "\\ul");
|
||||
break;
|
||||
case CFU_UNDERLINEDOTTED:
|
||||
case CFU_UNDERLINEDOTTED:
|
||||
strcat(props, "\\uld");
|
||||
break;
|
||||
case CFU_UNDERLINEDOUBLE:
|
||||
case CFU_UNDERLINEDOUBLE:
|
||||
strcat(props, "\\uldb");
|
||||
break;
|
||||
case CFU_UNDERLINEWORD:
|
||||
case CFU_UNDERLINEWORD:
|
||||
strcat(props, "\\ulw");
|
||||
break;
|
||||
case CFU_UNDERLINENONE:
|
||||
default:
|
||||
case CFU_CF1UNDERLINE:
|
||||
case CFU_UNDERLINENONE:
|
||||
default:
|
||||
strcat(props, "\\ulnone");
|
||||
break;
|
||||
}
|
||||
else if (fmt->dwEffects & CFE_UNDERLINE)
|
||||
strcat(props, "\\ul");
|
||||
}
|
||||
/* FIXME: How to emit CFM_WEIGHT? */
|
||||
|
||||
|
|
Loading…
Reference in New Issue