From 0c57065c73530bf30af12c6ce83f0db0680e74e1 Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Tue, 16 Aug 2016 14:30:18 +0200 Subject: [PATCH] GlyphCache: Erasing destination if not redundant. --- client/X11/xf_graphics.c | 2 +- include/freerdp/graphics.h | 2 +- libfreerdp/cache/glyph.c | 100 +++++++++++++++++++++++++++------------------ libfreerdp/gdi/graphics.c | 50 ++++++++++++++++++----- 4 files changed, 102 insertions(+), 52 deletions(-) diff --git a/client/X11/xf_graphics.c b/client/X11/xf_graphics.c index 71ed167..ce63207 100644 --- a/client/X11/xf_graphics.c +++ b/client/X11/xf_graphics.c @@ -355,7 +355,7 @@ static void xf_Glyph_Free(rdpContext* context, rdpGlyph* glyph) } static BOOL xf_Glyph_Draw(rdpContext* context, const rdpGlyph* glyph, UINT32 x, - UINT32 y) + UINT32 y, BOOL fOpRedundant) { xfGlyph* xf_glyph; xfContext* xfc = (xfContext*) context; diff --git a/include/freerdp/graphics.h b/include/freerdp/graphics.h index f1290ae..a4d1b748 100644 --- a/include/freerdp/graphics.h +++ b/include/freerdp/graphics.h @@ -119,7 +119,7 @@ FREERDP_API rdpPointer* Pointer_Alloc(rdpContext* context); typedef BOOL (*pGlyph_New)(rdpContext* context, const rdpGlyph* glyph); typedef void (*pGlyph_Free)(rdpContext* context, rdpGlyph* glyph); typedef BOOL (*pGlyph_Draw)(rdpContext* context, const rdpGlyph* glyph, - UINT32 x, UINT32 y); + UINT32 x, UINT32 y, BOOL fOpRedundant); typedef BOOL (*pGlyph_BeginDraw)(rdpContext* context, UINT32 x, UINT32 y, UINT32 width, UINT32 height, UINT32 bgcolor, UINT32 fgcolor, BOOL fOpRedundant); diff --git a/libfreerdp/cache/glyph.c b/libfreerdp/cache/glyph.c index 60ad331..11fadce 100644 --- a/libfreerdp/cache/glyph.c +++ b/libfreerdp/cache/glyph.c @@ -51,10 +51,10 @@ static UINT32 update_glyph_offset(const BYTE* data, UINT32 index, INT32* x, UINT32 offset = data[index++]; if (offset & 0x80) - { - offset = data[index++]; - offset |= ((UINT32)data[index++]) << 8; - } + { + offset = data[index++]; + offset |= ((UINT32)data[index++]) << 8; + } if (flAccel & SO_VERTICAL) *y += offset; @@ -67,8 +67,8 @@ static UINT32 update_glyph_offset(const BYTE* data, UINT32 index, INT32* x, } static BOOL update_process_glyph(rdpContext* context, const BYTE* data, - UINT32 cacheIndex, INT32* x, INT32* y, - UINT32 cacheId, UINT32 flAccel) + UINT32 cacheIndex, INT32* x, INT32* y, + UINT32 cacheId, UINT32 flAccel, BOOL fOpRedundant) { rdpGlyph* glyph; rdpGraphics* graphics; @@ -87,7 +87,7 @@ static BOOL update_process_glyph(rdpContext* context, const BYTE* data, if (glyph != NULL) { - if (!glyph->Draw(context, glyph, glyph->x + *x, glyph->y + *y)) + if (!glyph->Draw(context, glyph, glyph->x + *x, glyph->y + *y, fOpRedundant)) return FALSE; if (flAccel & SO_CHAR_INC_EQUAL_BM_BASE) @@ -143,18 +143,9 @@ static BOOL update_process_glyph_fragments(rdpContext* context, opWidth = context->settings->DesktopWidth - opX; } - if (opWidth > 0 && opHeight > 0) - { - if (!glyph->BeginDraw(context, opX, opY, opWidth, opHeight, bgcolor, fgcolor, - fOpRedundant)) - return FALSE; - } - else - { - if (!glyph->BeginDraw(context, bkX, bkY, bkWidth, bkHeight, bgcolor, fgcolor, - fOpRedundant)) - return FALSE; - } + if (!glyph->BeginDraw(context, opX, opY, opWidth, opHeight, bgcolor, fgcolor, + fOpRedundant)) + return FALSE; while (index < length) { @@ -181,7 +172,7 @@ static BOOL update_process_glyph_fragments(rdpContext* context, n = update_glyph_offset(fragments, n, &x, &y, ulCharInc, flAccel); if (!update_process_glyph(context, fragments, fop, &x, &y, cacheId, - flAccel)) + flAccel, fOpRedundant)) return FALSE; } } @@ -210,33 +201,40 @@ static BOOL update_process_glyph_fragments(rdpContext* context, default: index = update_glyph_offset(data, index, &x, &y, ulCharInc, flAccel); - if (!update_process_glyph(context, data, op, &x, &y, cacheId, flAccel)) + if (!update_process_glyph(context, data, op, &x, &y, cacheId, flAccel, + fOpRedundant)) return FALSE; break; } } - if ((opWidth > 0) && (opHeight > 0)) - return glyph->EndDraw(context, opX, opY, opWidth, opHeight, bgcolor, fgcolor); - else - return glyph->EndDraw(context, bkX, bkY, bkWidth, bkHeight, bgcolor, fgcolor); + return glyph->EndDraw(context, opX, opY, opWidth, opHeight, bgcolor, fgcolor); } static BOOL update_gdi_glyph_index(rdpContext* context, GLYPH_INDEX_ORDER* glyphIndex) { rdpGlyphCache* glyph_cache; - int bkWidth, bkHeight, opWidth, opHeight; + INT32 bkWidth = 0, bkHeight = 0, opWidth = 0, opHeight = 0; if (!context || !glyphIndex || !context->cache) return FALSE; glyph_cache = context->cache->glyph; - bkWidth = glyphIndex->bkRight - glyphIndex->bkLeft; - opWidth = glyphIndex->opRight - glyphIndex->opLeft; - bkHeight = glyphIndex->bkBottom - glyphIndex->bkTop; - opHeight = glyphIndex->opBottom - glyphIndex->opTop; + + if (glyphIndex->bkRight > glyphIndex->bkLeft) + bkWidth = glyphIndex->bkRight - glyphIndex->bkLeft + 1; + + if (glyphIndex->opRight > glyphIndex->opLeft) + opWidth = glyphIndex->opRight - glyphIndex->opLeft + 1; + + if (glyphIndex->bkBottom > glyphIndex->bkTop) + bkHeight = glyphIndex->bkBottom - glyphIndex->bkTop + 1; + + if (glyphIndex->opBottom > glyphIndex->opTop) + opHeight = glyphIndex->opBottom - glyphIndex->opTop + 1; + return update_process_glyph_fragments(context, glyphIndex->data, glyphIndex->cbData, glyphIndex->cacheId, glyphIndex->ulCharInc, glyphIndex->flAccel, @@ -253,6 +251,8 @@ static BOOL update_gdi_fast_index(rdpContext* context, INT32 opLeft, opTop; INT32 opRight, opBottom; rdpGlyphCache* glyph_cache; + INT32 opWidth = 0, opHeight = 0; + INT32 bkWidth = 0, bkHeight = 0; if (!context || !fastIndex || !context->cache) return FALSE; @@ -300,15 +300,24 @@ static BOOL update_gdi_fast_index(rdpContext* context, if (y == -32768) y = fastIndex->bkTop; + if (fastIndex->bkRight > fastIndex->bkLeft) + bkWidth = fastIndex->bkRight - fastIndex->bkLeft + 1; + + if (fastIndex->bkBottom > fastIndex->bkTop) + bkHeight = fastIndex->bkBottom - fastIndex->bkTop + 1; + + if (opRight > opLeft) + opWidth = opRight - opLeft + 1; + + if (opBottom > opTop) + opHeight = opBottom - opTop + 1; + return update_process_glyph_fragments(context, fastIndex->data, fastIndex->cbData, fastIndex->cacheId, fastIndex->ulCharInc, fastIndex->flAccel, fastIndex->backColor, fastIndex->foreColor, x, y, - fastIndex->bkLeft, fastIndex->bkTop, - fastIndex->bkRight - fastIndex->bkLeft, fastIndex->bkBottom - fastIndex->bkTop, - opLeft, opTop, - opRight - opLeft, opBottom - opTop, - FALSE); + fastIndex->bkLeft, fastIndex->bkTop, bkWidth, bkHeight, + opLeft, opTop, opWidth, opHeight, FALSE); } static BOOL update_gdi_fast_glyph(rdpContext* context, @@ -318,6 +327,8 @@ static BOOL update_gdi_fast_glyph(rdpContext* context, BYTE text_data[2]; INT32 opLeft, opTop; INT32 opRight, opBottom; + INT32 opWidth = 0, opHeight = 0; + INT32 bkWidth = 0, bkHeight = 0; rdpCache* cache; if (!context || !fastGlyph || !context->cache) @@ -385,14 +396,25 @@ static BOOL update_gdi_fast_glyph(rdpContext* context, text_data[0] = fastGlyph->data[0]; text_data[1] = 0; + + if (fastGlyph->bkRight > fastGlyph->bkLeft) + bkWidth = fastGlyph->bkRight - fastGlyph->bkLeft + 1; + + if (fastGlyph->bkBottom > fastGlyph->bkTop) + bkHeight = fastGlyph->bkBottom - fastGlyph->bkTop + 1; + + if (opRight > opLeft) + opWidth = opRight - opLeft + 1; + + if (opBottom > opTop) + opHeight = opBottom - opTop + 1; + return update_process_glyph_fragments(context, text_data, 1, fastGlyph->cacheId, fastGlyph->ulCharInc, fastGlyph->flAccel, fastGlyph->backColor, fastGlyph->foreColor, x, y, fastGlyph->bkLeft, fastGlyph->bkTop, - fastGlyph->bkRight - fastGlyph->bkLeft, fastGlyph->bkBottom - fastGlyph->bkTop, - opLeft, opTop, - opRight - opLeft, opBottom - opTop, - FALSE); + bkWidth, bkHeight, opLeft, opTop, + opWidth, opHeight, FALSE); } static BOOL update_gdi_cache_glyph(rdpContext* context, diff --git a/libfreerdp/gdi/graphics.c b/libfreerdp/gdi/graphics.c index eb459c3..0bc4070 100644 --- a/libfreerdp/gdi/graphics.c +++ b/libfreerdp/gdi/graphics.c @@ -255,19 +255,29 @@ static void gdi_Glyph_Free(rdpContext* context, rdpGlyph* glyph) } static BOOL gdi_Glyph_Draw(rdpContext* context, const rdpGlyph* glyph, UINT32 x, - UINT32 y) + UINT32 y, BOOL fOpRedundant) { gdiGlyph* gdi_glyph; rdpGdi* gdi; + HGDI_BRUSH brush; + BOOL rc = FALSE; if (!context || !glyph) return FALSE; gdi = context->gdi; gdi_glyph = (gdiGlyph*) glyph; - return gdi_BitBlt(gdi->drawing->hdc, x, y, gdi_glyph->bitmap->width, - gdi_glyph->bitmap->height, gdi_glyph->hdc, 0, 0, - GDI_GLYPH_ORDER, &context->gdi->palette); + brush = gdi_CreateSolidBrush(gdi->drawing->hdc->textColor); + + if (!brush) + return FALSE; + + gdi_SelectObject(gdi->drawing->hdc, (HGDIOBJECT)brush); + rc = gdi_BitBlt(gdi->drawing->hdc, x, y, gdi_glyph->bitmap->width, + gdi_glyph->bitmap->height, gdi_glyph->hdc, 0, 0, + GDI_GLYPH_ORDER, &context->gdi->palette); + gdi_DeleteObject((HGDIOBJECT)brush); + return rc; } static BOOL gdi_Glyph_BeginDraw(rdpContext* context, UINT32 x, UINT32 y, @@ -290,13 +300,33 @@ static BOOL gdi_Glyph_BeginDraw(rdpContext* context, UINT32 x, UINT32 y, if (!gdi_decode_color(gdi, fgcolor, &fgcolor, NULL)) return FALSE; - gdi->drawing->hdc->brush = gdi_CreateSolidBrush(bgcolor); - - if (!gdi->drawing->hdc->brush) - return FALSE; - gdi_SetTextColor(gdi->drawing->hdc, bgcolor); gdi_SetBkColor(gdi->drawing->hdc, fgcolor); + + if (!fOpRedundant) + { + GDI_RECT rect = { 0 }; + HGDI_BRUSH brush = gdi_CreateSolidBrush(fgcolor); + + if (!brush) + return FALSE; + + if (x > 0) + rect.left = x; + + if (y > 0) + rect.top = y; + + if (x + width > 0) + rect.right = x + width - 1; + + if (y + height > 0) + rect.bottom = y + height - 1; + + gdi_FillRect(gdi->drawing->hdc, &rect, brush); + gdi_DeleteObject((HGDIOBJECT)brush); + } + return gdi_SetClipRgn(gdi->drawing->hdc, x, y, width, height); } @@ -313,8 +343,6 @@ static BOOL gdi_Glyph_EndDraw(rdpContext* context, UINT32 x, UINT32 y, if (!gdi->drawing || !gdi->drawing->hdc) return FALSE; - gdi_DeleteObject((HGDIOBJECT)gdi->drawing->hdc->brush); - gdi->drawing->hdc->brush = NULL; gdi_SetNullClipRgn(gdi->drawing->hdc); return TRUE; } -- 2.7.4