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:
parent
da9bc7cd95
commit
6f1cc1f3b5
|
@ -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 );
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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 )
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue