[PATCH 2/6] riched20: Fix the interaction between CFE_UNDERLINE and bUnderlineType.
Huw Davies
huw at codeweavers.com
Fri Oct 14 04:05:03 CDT 2016
The effect specifies whether underlining is turned on, while bUnderlineType
indicates the type of underlining.
Signed-off-by: Huw Davies <huw at codeweavers.com>
---
dlls/riched20/editor.c | 29 +++++++++-------
dlls/riched20/paint.c | 2 +-
dlls/riched20/para.c | 3 +-
dlls/riched20/run.c | 10 ------
dlls/riched20/style.c | 53 ++++++++---------------------
dlls/riched20/tests/editor.c | 79 ++++++++++++++++++++++++++++++++++++++++++++
dlls/riched20/writer.c | 23 ++++++-------
7 files changed, 124 insertions(+), 75 deletions(-)
diff --git a/dlls/riched20/editor.c b/dlls/riched20/editor.c
index 8b94ccf..1ce444e 100644
--- a/dlls/riched20/editor.c
+++ b/dlls/riched20/editor.c
@@ -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;
diff --git a/dlls/riched20/paint.c b/dlls/riched20/paint.c
index b76f533..41b3896 100644
--- a/dlls/riched20/paint.c
+++ b/dlls/riched20/paint.c
@@ -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)
{
diff --git a/dlls/riched20/para.c b/dlls/riched20/para.c
index f050b2e..3f54fea 100644
--- a/dlls/riched20/para.c
+++ b/dlls/riched20/para.c
@@ -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;
diff --git a/dlls/riched20/run.c b/dlls/riched20/run.c
index 496f0f9..098c4f8 100644
--- a/dlls/riched20/run.c
+++ b/dlls/riched20/run.c
@@ -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;
- }
}
/******************************************************************************
diff --git a/dlls/riched20/style.c b/dlls/riched20/style.c
index 0d2c16a..1a944cbb 100644
--- a/dlls/riched20/style.c
+++ b/dlls/riched20/style.c
@@ -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;
diff --git a/dlls/riched20/tests/editor.c b/dlls/riched20/tests/editor.c
index 8d7d209..bfc61ea 100644
--- a/dlls/riched20/tests/editor.c
+++ b/dlls/riched20/tests/editor.c
@@ -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);
}
diff --git a/dlls/riched20/writer.c b/dlls/riched20/writer.c
index 77f50e3..8ecc1601 100644
--- a/dlls/riched20/writer.c
+++ b/dlls/riched20/writer.c
@@ -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? */
--
2.8.2
More information about the wine-patches
mailing list