riched20: Allow the style to remain selected in the context.

This avoids swapping out the font if the next run uses the same style.

Signed-off-by: Huw Davies <huw@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Huw Davies 2019-08-19 10:55:28 +01:00 committed by Alexandre Julliard
parent da9bc7cd95
commit 6f1cc1f3b5
8 changed files with 76 additions and 75 deletions

View File

@ -27,6 +27,8 @@ void ME_InitContext(ME_Context *c, ME_TextEditor *editor, HDC hDC)
c->pt.x = 0;
c->pt.y = 0;
c->rcView = editor->rcFormat;
c->current_style = NULL;
c->orig_font = NULL;
if (hDC) {
c->dpi.cx = GetDeviceCaps(hDC, LOGPIXELSX);
c->dpi.cy = GetDeviceCaps(hDC, LOGPIXELSY);
@ -41,5 +43,6 @@ void ME_InitContext(ME_Context *c, ME_TextEditor *editor, HDC hDC)
void ME_DestroyContext(ME_Context *c)
{
if (c->hDC) ITextHost_TxReleaseDC(c->editor->texthost, c->hDC);
select_style( c, NULL );
if (c->hDC) ITextHost_TxReleaseDC( c->editor->texthost, c->hDC );
}

View File

@ -53,8 +53,7 @@ void ME_DestroyStyle(ME_Style *item) DECLSPEC_HIDDEN;
void ME_ReleaseStyle(ME_Style *item) DECLSPEC_HIDDEN;
ME_Style *ME_GetInsertStyle(ME_TextEditor *editor, int nCursor) DECLSPEC_HIDDEN;
ME_Style *ME_ApplyStyle(ME_TextEditor *ed, ME_Style *sSrc, CHARFORMAT2W *style) DECLSPEC_HIDDEN;
HFONT ME_SelectStyleFont(ME_Context *c, ME_Style *s) DECLSPEC_HIDDEN;
void ME_UnselectStyleFont(ME_Context *c, ME_Style *s, HFONT hOldFont) DECLSPEC_HIDDEN;
void select_style(ME_Context *c, ME_Style *s) DECLSPEC_HIDDEN;
void ME_InitCharFormat2W(CHARFORMAT2W *pFmt) DECLSPEC_HIDDEN;
void ME_SaveTempStyle(ME_TextEditor *editor, ME_Style *style) DECLSPEC_HIDDEN;
void ME_ClearTempStyle(ME_TextEditor *editor) DECLSPEC_HIDDEN;

View File

@ -457,6 +457,8 @@ typedef struct tagME_Context
RECT rcView;
SIZE dpi;
int nAvailWidth;
ME_Style *current_style;
HFONT orig_font;
/* those are valid inside ME_WrapTextParagraph and related */
ME_TextEditor *editor;

View File

@ -290,11 +290,10 @@ static void draw_space( ME_Context *c, ME_Run *run, int x, int y,
{
COLORREF text_color = get_text_color( c, run->style, selected );
COLORREF old_text, old_back;
HFONT old_font = NULL;
int y_offset = calc_y_offset( c, run->style );
static const WCHAR space[1] = {' '};
old_font = ME_SelectStyleFont( c, run->style );
select_style( c, run->style );
old_text = SetTextColor( hdc, text_color );
if (selected) old_back = SetBkColor( hdc, back_color );
@ -302,7 +301,6 @@ static void draw_space( ME_Context *c, ME_Run *run, int x, int y,
if (selected) SetBkColor( hdc, old_back );
SetTextColor( hdc, old_text );
ME_UnselectStyleFont( c, run->style, old_font );
draw_underline( c, run, x, y - y_offset, text_color );
}
@ -370,7 +368,6 @@ static void ME_DrawTextWithStyle(ME_Context *c, ME_Run *run, int x, int y,
int nSelFrom, int nSelTo, int ymin, int cy)
{
HDC hDC = c->hDC;
HGDIOBJ hOldFont;
int yOffset = 0;
BOOL selected = (nSelFrom < run->len && nSelTo >= 0
&& nSelFrom < nSelTo && !c->editor->bHideSelection &&
@ -403,7 +400,7 @@ static void ME_DrawTextWithStyle(ME_Context *c, ME_Run *run, int x, int y,
}
}
hOldFont = ME_SelectStyleFont( c, run->style );
select_style( c, run->style );
if (sel_rgn) ExtSelectClipRgn( hDC, sel_rgn, RGN_DIFF );
@ -430,8 +427,6 @@ static void ME_DrawTextWithStyle(ME_Context *c, ME_Run *run, int x, int y,
if (old_style_selected)
PatBlt( hDC, sel_rect.left, ymin, sel_rect.right - sel_rect.left, cy, DSTINVERT );
ME_UnselectStyleFont(c, run->style, hOldFont);
}
static void ME_DebugWrite(HDC hDC, const POINT *pt, LPCWSTR szText) {
@ -900,13 +895,12 @@ static void ME_DrawTableBorders(ME_Context *c, ME_DisplayItem *paragraph)
static void draw_para_number( ME_Context *c, ME_DisplayItem *p )
{
ME_Paragraph *para = &p->member.para;
HFONT old_font;
int x, y;
COLORREF old_text;
if (para->fmt.wNumbering)
{
old_font = ME_SelectStyleFont( c, para->para_num.style );
select_style( c, para->para_num.style );
old_text = SetTextColor( c->hDC, get_text_color( c, para->para_num.style, FALSE ) );
x = c->pt.x + para->para_num.pt.x;
@ -915,7 +909,6 @@ static void draw_para_number( ME_Context *c, ME_DisplayItem *p )
ExtTextOutW( c->hDC, x, y, 0, NULL, para->para_num.text->szData, para->para_num.text->nLen, NULL );
SetTextColor( c->hDC, old_text );
ME_UnselectStyleFont( c, para->para_num.style, old_font );
}
}

View File

@ -399,7 +399,6 @@ void para_num_init( ME_Context *c, ME_Paragraph *para )
static const WCHAR bullet_font[] = {'S','y','m','b','o','l',0};
static const WCHAR bullet_str[] = {0xb7, 0};
static const WCHAR spaceW[] = {' ', 0};
HFONT old_font;
SIZE sz;
if (para->para_num.style && para->para_num.text) return;
@ -432,12 +431,11 @@ void para_num_init( ME_Context *c, ME_Paragraph *para )
para->para_num.text = ME_MakeStringConst( bullet_str, 1 );
}
old_font = ME_SelectStyleFont( c, para->para_num.style );
select_style( c, para->para_num.style );
GetTextExtentPointW( c->hDC, para->para_num.text->szData, para->para_num.text->nLen, &sz );
para->para_num.width = sz.cx;
GetTextExtentPointW( c->hDC, spaceW, 1, &sz );
para->para_num.width += sz.cx;
ME_UnselectStyleFont( c, para->para_num.style, old_font );
}
void para_num_clear( struct para_num *pn )

View File

@ -459,7 +459,6 @@ int ME_CharFromPointContext(ME_Context *c, int cx, ME_Run *run, BOOL closest, BO
ME_String *mask_text = NULL;
WCHAR *str;
int fit = 0;
HGDIOBJ hOldFont;
SIZE sz, sz2, sz3;
if (!run->len || cx <= 0)
return 0;
@ -498,7 +497,7 @@ int ME_CharFromPointContext(ME_Context *c, int cx, ME_Run *run, BOOL closest, BO
else
str = get_text( run, 0 );
hOldFont = ME_SelectStyleFont(c, run->style);
select_style(c, run->style);
GetTextExtentExPointW(c->hDC, str, run->len,
cx, &fit, NULL, &sz);
if (closest && fit != run->len)
@ -511,7 +510,6 @@ int ME_CharFromPointContext(ME_Context *c, int cx, ME_Run *run, BOOL closest, BO
ME_DestroyString( mask_text );
ME_UnselectStyleFont(c, run->style, hOldFont);
return fit;
}
@ -533,15 +531,16 @@ int ME_CharFromPoint(ME_TextEditor *editor, int cx, ME_Run *run, BOOL closest, B
*/
static void ME_GetTextExtent(ME_Context *c, LPCWSTR szText, int nChars, ME_Style *s, SIZE *size)
{
HGDIOBJ 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;
}
if (c->hDC)
{
select_style( c, s );
GetTextExtentPoint32W( c->hDC, szText, nChars, size );
}
else
{
size->cx = 0;
size->cy = 0;
}
}
/******************************************************************************

View File

@ -366,67 +366,77 @@ static void release_font_cache(ME_FontCacheItem *item)
}
}
HFONT ME_SelectStyleFont( ME_Context *c, ME_Style *s )
void select_style( ME_Context *c, ME_Style *s )
{
HFONT old_font;
LOGFONTW lf;
int i, empty, age = 0x7FFFFFFF;
ME_FontCacheItem *item;
assert( s );
if (c->current_style == s) return;
ME_LogFontFromStyle( c, &lf, s );
for (i = 0; i < HFONT_CACHE_SIZE; i++)
c->editor->pFontCache[i].nAge++;
for (i = 0, empty = -1, age = 0; i < HFONT_CACHE_SIZE; i++)
if (s)
{
item = &c->editor->pFontCache[i];
if (!item->nRefs)
ME_LogFontFromStyle( c, &lf, s );
for (i = 0; i < HFONT_CACHE_SIZE; i++)
c->editor->pFontCache[i].nAge++;
for (i = 0, empty = -1, age = 0; i < HFONT_CACHE_SIZE; i++)
{
if (item->nAge > age)
item = &c->editor->pFontCache[i];
if (!item->nRefs)
{
empty = i;
age = item->nAge;
if (item->nAge > age)
{
empty = i;
age = item->nAge;
}
}
if (item->hFont && ME_IsFontEqual( &item->lfSpecs, &lf ))
break;
}
if (item->hFont && ME_IsFontEqual( &item->lfSpecs, &lf ))
break;
}
if (i < HFONT_CACHE_SIZE) /* found */
{
item = &c->editor->pFontCache[i];
TRACE_(richedit_style)( "font reused %d\n", i );
item->nRefs++;
if (i < HFONT_CACHE_SIZE) /* found */
{
item = &c->editor->pFontCache[i];
TRACE_(richedit_style)( "font reused %d\n", i );
item->nRefs++;
}
else
{
assert(empty != -1);
item = &c->editor->pFontCache[empty];
if (item->hFont)
{
TRACE_(richedit_style)( "font deleted %d\n", empty );
DeleteObject(item->hFont);
item->hFont = NULL;
}
item->hFont = CreateFontIndirectW( &lf );
TRACE_(richedit_style)( "font created %d\n", empty );
item->nRefs = 1;
item->lfSpecs = lf;
}
s->font_cache = item;
old_font = SelectObject( c->hDC, item->hFont );
GetTextMetricsW( c->hDC, &s->tm );
if (!c->orig_font) c->orig_font = old_font;
}
else
{
assert(empty != -1);
item = &c->editor->pFontCache[empty];
if (item->hFont)
{
TRACE_(richedit_style)( "font deleted %d\n", empty );
DeleteObject(item->hFont);
item->hFont = NULL;
}
item->hFont = CreateFontIndirectW( &lf );
TRACE_(richedit_style)( "font created %d\n", empty );
item->nRefs = 1;
item->lfSpecs = lf;
SelectObject( c->hDC, c->orig_font );
c->orig_font = NULL;
}
s->font_cache = item;
old_font = SelectObject( c->hDC, item->hFont );
GetTextMetricsW( c->hDC, &s->tm );
return old_font;
}
void ME_UnselectStyleFont(ME_Context *c, ME_Style *s, HFONT hOldFont)
{
SelectObject(c->hDC, hOldFont);
release_font_cache(s->font_cache);
s->font_cache = NULL;
if (c->current_style)
{
release_font_cache( c->current_style->font_cache );
c->current_style->font_cache = NULL;
}
c->current_style = s;
return;
}
void ME_DestroyStyle(ME_Style *s)

View File

@ -65,7 +65,6 @@ static BOOL get_run_glyph_buffers( ME_Run *run )
static HRESULT shape_run( ME_Context *c, ME_Run *run )
{
HRESULT hr;
HFONT old_font;
int i;
if (!run->glyphs)
@ -82,7 +81,7 @@ static HRESULT shape_run( ME_Context *c, ME_Run *run )
run->clusters = heap_alloc( run->max_clusters * sizeof(WORD) );
}
old_font = ME_SelectStyleFont( c, run->style );
select_style( c, run->style );
while (1)
{
hr = ScriptShape( c->hDC, &run->style->script_cache, get_text( run, 0 ), run->len, run->max_glyphs,
@ -103,8 +102,6 @@ static HRESULT shape_run( ME_Context *c, ME_Run *run )
run->nWidth += run->advances[i];
}
ME_UnselectStyleFont( c, run->style, old_font );
return hr;
}