I was just about to send in the same patch when you did. I'll have to keep you updated on what I'm working on in the future. (You can see what I'm planning to do for my SoC project at http://wiki.winehq.org/MatthewFinnicum)
I've attached the patch I was going to send - I suggest we use some parts of each (either I can merge them into a patch or you can, your call).
Our code is actually quite similar - though your "ME_CharFormatFromLogFont" is definitely superior to mine (I just did it all in function / was slightly less awesome).
Aside from my conformance tests (Which your patch passed just fine), my patch covers some extra things:
1) You need to rewrap the paragraphs, since line lengths change. 2) Your code ignores lParam (which is supposed to specify if it repaints immediately) 3) You need to invalidate the entire control - otherwise just the are the text takes up will be redrawn - if the text shrinks, then the area outside it's new size won't be blanked / you'll see fragments of the old text. 4) Your code (I believe) will reset the scroll position - I store it ahead of time and then restore it.
Thanks, --Matt
On 6/24/06, Krzysztof Foltman wdev@foltman.com wrote:
ChangeLog:
- WM_SETFONT implementation - sets the default font and the font for
the whole pre-existing text
Seems to fix bug 4563 and half of the bug 3917.
Krzysztof
diff --git a/dlls/riched20/editor.c b/dlls/riched20/editor.c old mode 100644 new mode 100755 index 50527ca..61ecc72 --- a/dlls/riched20/editor.c +++ b/dlls/riched20/editor.c @@ -92,7 +92,7 @@
- EM_SELECTIONTYPE
- EM_SETBIDIOPTIONS 3.0
- EM_SETBKGNDCOLOR
- EM_SETCHARFORMAT (partly done, no ANSI)
- EM_SETCHARFORMAT (partly done, no ANSI)
- EM_SETEDITSTYLE
- EM_SETEVENTMASK (few notifications supported)
- EM_SETFONTSIZE
@@ -135,7 +135,7 @@
- WM_GETTEXT (ANSI&Unicode)
- WM_GETTEXTLENGTH (ANSI version sucks)
- WM_PASTE
- WM_SETFONT
- WM_SETFONT
- WM_SETTEXT (resets undo stack !) (proper style?) ANSI&Unicode
- WM_STYLECHANGING
- WM_STYLECHANGED (things like read-only flag)
@@ -1442,7 +1442,6 @@ LRESULT WINAPI RichEditANSIWndProc(HWND UNSUPPORTED_MSG(EM_SETTYPOGRAPHYOPTIONS) UNSUPPORTED_MSG(EM_SETWORDBREAKPROCEX) UNSUPPORTED_MSG(EM_SHOWSCROLLBAR)
- UNSUPPORTED_MSG(WM_SETFONT) UNSUPPORTED_MSG(WM_STYLECHANGING) UNSUPPORTED_MSG(WM_STYLECHANGED)
/* UNSUPPORTED_MSG(WM_UNICHAR) FIXME missing in Wine headers */ @@ -1844,6 +1843,27 @@ LRESULT WINAPI RichEditANSIWndProc(HWND
return 0;
}
- case WM_SETFONT:
- {
- LOGFONTW lf;
- CHARFORMAT2W fmt;
- HDC hDC;
- BOOL bRepaint = LOWORD(lParam);
- if (!wParam)
wParam = (WPARAM)GetStockObject(DEFAULT_GUI_FONT);
- GetObjectW((HGDIOBJ)wParam, sizeof(LOGFONTW), &lf);
- hDC = GetDC(hWnd);
- ME_CharFormatFromLogFont(hDC, &lf, &fmt);
- ReleaseDC(hWnd, hDC);
- ME_SetCharFormat(editor, 0, ME_GetTextLength(editor), &fmt);
- ME_SetDefaultCharFormat(editor, &fmt);
- ME_CommitUndo(editor);
- if (bRepaint)
ME_UpdateRepaint(editor);
- return 0;
- } case WM_SETTEXT: { ME_InternalDeleteText(editor, 0, ME_GetTextLength(editor));
diff --git a/dlls/riched20/editor.h b/dlls/riched20/editor.h old mode 100644 new mode 100755 index 33b7626..a4d4980 --- a/dlls/riched20/editor.h +++ b/dlls/riched20/editor.h @@ -55,6 +55,7 @@ void ME_CopyToCF2W(CHARFORMAT2W *to, CHA CHARFORMAT2W *ME_ToCFAny(CHARFORMAT2W *to, CHARFORMAT2W *from); void ME_CopyToCFAny(CHARFORMAT2W *to, CHARFORMAT2W *from); void ME_CopyCharFormat(CHARFORMAT2W *pDest, CHARFORMAT2W *pSrc); /* only works with 2W structs */ +void ME_CharFormatFromLogFont(HDC hDC, LOGFONTW *lf, CHARFORMAT2W *fmt); /* ditto */
/* list.c */ void ME_InsertBefore(ME_DisplayItem *diWhere, ME_DisplayItem *diWhat); diff --git a/dlls/riched20/style.c b/dlls/riched20/style.c old mode 100644 new mode 100755 index f420f09..6104a0c --- a/dlls/riched20/style.c +++ b/dlls/riched20/style.c @@ -286,6 +286,25 @@ ME_LogFontFromStyle(HDC hDC, LOGFONTW *l lf->lfCharSet = s->fmt.bCharSet; }
+void ME_CharFormatFromLogFont(HDC hDC, LOGFONTW *lf, CHARFORMAT2W *fmt) +{
- int rx, ry;
- ME_InitCharFormat2W(fmt);
- rx = GetDeviceCaps(hDC, LOGPIXELSX);
- 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->wWeight = lf->lfWeight;
- fmt->yHeight = -lf->lfHeight*1440/ry;
- if (lf->lfWeight>400) fmt->dwEffects |= CFM_BOLD;
- if (lf->lfItalic) fmt->dwEffects |= CFM_ITALIC;
- if (lf->lfUnderline) fmt->dwEffects |= CFM_UNDERLINE;
- if (lf->lfStrikeOut) fmt->dwEffects |= CFM_STRIKEOUT;
- fmt->bPitchAndFamily = lf->lfPitchAndFamily;
- fmt->bCharSet = lf->lfCharSet;
+}
BOOL ME_IsFontEqual(LOGFONTW *p1, LOGFONTW *p2) {
Matt Finnicum wrote:
I was just about to send in the same patch when you did. I'll have to keep you updated on what I'm working on in the future.
That'd be nice - as I mostly stopped doing riched20 stuff for quite some time, and only got back to it a few days ago.
I've attached the patch I was going to send - I suggest we use some parts of each (either I can merge them into a patch or you can, your call).
I'm definitely for using your conformance test code. And WM_GETFONT. Not sure about the rest - the code in my patch is based on implementation of EM_SETCHARFORMAT, so it's basically as good as that one.
- You need to rewrap the paragraphs, since line lengths change.
Yes, but SetCharFormat already does it internally (run.c:624), so there's no need to explicitly call it again.
- Your code ignores lParam (which is supposed to specify if it
repaints immediately)
It does not, it assigns it to bRepaint and then uses in a condition. So it's a correct solution.
- You need to invalidate the entire control - otherwise just the are
the text takes up will be redrawn - if the text shrinks, then the area outside it's new size won't be blanked / you'll see fragments of the old text.
I'm not sure how the original control is behaving - going with InvalidateRect, no matter if it's necessary or not, won't harm. However, it should be done in ME_SetCharFormat, so that both EM_SETCHARFORMAT and WM_SETFONT (and other functions) will use it.
- Your code (I believe) will reset the scroll position - I store it
ahead of time and then restore it.
And that is actually wrong - keep in mind that scroll position is expressed in pixels, and the new font may be sometimes much smaller than the old one.
I think the scroll position update code belongs to ME_SetCharFormat, and should be added there in a separate patch. Compare WM_SETFONT to EM_SETCHARFORMAT and you'll know why.
The plan is: if my original patch gets accepted, then you can extract the testing code and WM_GETFONT handler which is missing in my implementation and send it as a separate patch. This will avoid the mess related to combining those two patches into one.
When this stuff is finished, I'd suggest you try implementing the ES_PASSWORD-related stuff, combined with WM_SETFONT handling it would let us fix a couple Bugzilla reports :) It should be pretty straightforward and independent of other parts of the code. And I'm not going to touch that stuff now.
Krzysztof
On 6/25/06, Krzysztof Foltman wdev@foltman.com wrote:
I'm definitely for using your conformance test code. And WM_GETFONT. Not sure about the rest - the code in my patch is based on implementation of EM_SETCHARFORMAT, so it's basically as good as that one.
Actually, GETFONT was a mistake - it turns out it doesn't exist for rich edit controls.
- You need to rewrap the paragraphs, since line lengths change.
Yes, but SetCharFormat already does it internally (run.c:624), so there's no need to explicitly call it again.
I had some issues with rewrapping not happening when I was testing with mine, but it appears to be working fine on yours. A long line, after being SETFONT'd to a larger font, would have overlapping text.
- Your code ignores lParam (which is supposed to specify if it
repaints immediately)
Ahh. Missed that somehow.
- You need to invalidate the entire control - otherwise just the are
the text takes up will be redrawn - if the text shrinks, then the area outside it's new size won't be blanked / you'll see fragments of the old text.
I'm not sure how the original control is behaving - going with InvalidateRect, no matter if it's necessary or not, won't harm. However, it should be done in ME_SetCharFormat, so that both EM_SETCHARFORMAT and WM_SETFONT (and other functions) will use it.
Sounds good - I didn't test how SetCharFormat was behaving, but you're right - it's probably needed by both. The redraw glitch can be pretty obvious (just change any chunk of text to a smaller font)
- Your code (I believe) will reset the scroll position - I store it
ahead of time and then restore it.
And that is actually wrong - keep in mind that scroll position is expressed in pixels, and the new font may be sometimes much smaller than the old one.
I think the scroll position update code belongs to ME_SetCharFormat, and should be added there in a separate patch. Compare WM_SETFONT to EM_SETCHARFORMAT and you'll know why.
Sounds good to me. When it is implemented, I'll add a conformance test for the scrolling behaviour, too.
The plan is: if my original patch gets accepted, then you can extract the testing code and WM_GETFONT handler which is missing in my implementation and send it as a separate patch. This will avoid the mess related to combining those two patches into one.
MMkay. Will do!
When this stuff is finished, I'd suggest you try implementing the ES_PASSWORD-related stuff, combined with WM_SETFONT handling it would let us fix a couple Bugzilla reports :) It should be pretty straightforward and independent of other parts of the code. And I'm not going to touch that stuff now.
Most Excellent. ES_PASSWORD (actually I wrote about a third of it already) is only supposed to affect single-line controls, but I could always just implement it for all rich edit controls, and that'll right itself when single-line is implemented. That would probably make more sense, as I doubt anything relies on the "Does nothing if it's not a single-line control" behaviour.
Actually, after implementing that there's a bunch of styles I could add somewhat easily, like WS_SETFONT.
Thanks for the help / I'll let ya know what I'm working on. --Matt