From 161685b25cbbd09cae52df4b2e933bedf47e61f0 Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Wed, 17 Aug 2016 09:26:59 +0200 Subject: [PATCH] Fixed some more glyph chache bugs. --- client/X11/xf_graphics.c | 38 ++++-- include/freerdp/graphics.h | 3 +- libfreerdp/cache/glyph.c | 301 +++++++++++++++++++++++++++++---------------- libfreerdp/gdi/graphics.c | 45 +++++-- 4 files changed, 262 insertions(+), 125 deletions(-) diff --git a/client/X11/xf_graphics.c b/client/X11/xf_graphics.c index ce63207..0e162dc 100644 --- a/client/X11/xf_graphics.c +++ b/client/X11/xf_graphics.c @@ -355,15 +355,29 @@ static void xf_Glyph_Free(rdpContext* context, rdpGlyph* glyph) } static BOOL xf_Glyph_Draw(rdpContext* context, const rdpGlyph* glyph, UINT32 x, - UINT32 y, BOOL fOpRedundant) + UINT32 y, UINT32 w, UINT32 h, UINT32 sx, UINT32 sy, + BOOL fOpRedundant) { xfGlyph* xf_glyph; xfContext* xfc = (xfContext*) context; xf_glyph = (xfGlyph*) glyph; xf_lock_x11(xfc, FALSE); + + if (!fOpRedundant) + { + XSetFillStyle(xfc->display, xfc->gc, FillOpaqueStippled); + XFillRectangle(xfc->display, xfc->drawable, xfc->gc, x, y, w, h); + } + + XSetFillStyle(xfc->display, xfc->gc, FillStippled); XSetStipple(xfc->display, xfc->gc, xf_glyph->pixmap); + + if (sx || sy) + WLog_ERR(TAG, ""); + + //XSetClipOrigin(xfc->display, xfc->gc, sx, sy); XSetTSOrigin(xfc->display, xfc->gc, x, y); - XFillRectangle(xfc->display, xfc->drawing, xfc->gc, x, y, glyph->cx, glyph->cy); + XFillRectangle(xfc->display, xfc->drawing, xfc->gc, x, y, w, h); xf_unlock_x11(xfc, FALSE); return TRUE; } @@ -386,11 +400,18 @@ static BOOL xf_Glyph_BeginDraw(rdpContext* context, UINT32 x, UINT32 y, rect.width = width; rect.height = height; xf_lock_x11(xfc, FALSE); + + if (!fOpRedundant) + { + XSetForeground(xfc->display, xfc->gc, fgcolor); + XSetBackground(xfc->display, xfc->gc, fgcolor); + XSetFillStyle(xfc->display, xfc->gc, FillOpaqueStippled); + XClearArea(xfc->display, xfc->drawable, xfc->gc, x, y, width, height); + XFillRectangle(xfc->display, xfc->drawable, xfc->gc, x, y, width, height); + } + XSetForeground(xfc->display, xfc->gc, bgcolor); XSetBackground(xfc->display, xfc->gc, fgcolor); - XSetFillStyle(xfc->display, xfc->gc, - fOpRedundant ? FillOpaqueStippled : FillStippled); - XFillRectangle(xfc->display, xfc->drawable, xfc->gc, x, y, width, height); xf_unlock_x11(xfc, FALSE); return TRUE; } @@ -408,16 +429,9 @@ static BOOL xf_Glyph_EndDraw(rdpContext* context, UINT32 x, UINT32 y, if (!xf_decode_color(context->gdi, fgcolor, &fgcolor, NULL)) return FALSE; - xf_lock_x11(xfc, FALSE); - XSetFillStyle(xfc->display, xfc->gc, FillOpaqueStippled); - XSetForeground(xfc->display, xfc->gc, fgcolor); - XSetBackground(xfc->display, xfc->gc, bgcolor); - XFillRectangle(xfc->display, xfc->drawable, xfc->gc, x, y, width, height); - if (xfc->drawing == xfc->primary) ret = gdi_InvalidateRegion(xfc->hdc, x, y, width, height); - xf_unlock_x11(xfc, FALSE); return ret; } diff --git a/include/freerdp/graphics.h b/include/freerdp/graphics.h index a4d1b748..6bf534c 100644 --- a/include/freerdp/graphics.h +++ b/include/freerdp/graphics.h @@ -119,7 +119,8 @@ 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, BOOL fOpRedundant); + UINT32 x, UINT32 y, UINT32 w, UINT32 h, + UINT32 sx, UINT32 sy, 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 11fadce..5a90515 100644 --- a/libfreerdp/cache/glyph.c +++ b/libfreerdp/cache/glyph.c @@ -34,17 +34,17 @@ #define TAG FREERDP_TAG("cache.glyph") static rdpGlyph* glyph_cache_get(rdpGlyphCache* glyph_cache, UINT32 id, - UINT32 index); + UINT32 index); static BOOL glyph_cache_put(rdpGlyphCache* glyph_cache, UINT32 id, UINT32 index, - rdpGlyph* entry); + rdpGlyph* entry); -static void* glyph_cache_fragment_get(rdpGlyphCache* glyph, UINT32 index, - UINT32* count); -static void glyph_cache_fragment_put(rdpGlyphCache* glyph, UINT32 index, - UINT32 count, void* entry); +static const void* glyph_cache_fragment_get(rdpGlyphCache* glyph, UINT32 index, + UINT32* count); +static BOOL glyph_cache_fragment_put(rdpGlyphCache* glyph, UINT32 index, + UINT32 count, const void* entry); static UINT32 update_glyph_offset(const BYTE* data, UINT32 index, INT32* x, - INT32* y, UINT32 ulCharInc, UINT32 flAccel) + INT32* y, UINT32 ulCharInc, UINT32 flAccel) { if ((ulCharInc == 0) && (!(flAccel & SO_CHAR_INC_EQUAL_BM_BASE))) { @@ -67,9 +67,12 @@ 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, BOOL fOpRedundant) + UINT32 cacheIndex, INT32* x, INT32* y, + UINT32 cacheId, UINT32 flAccel, BOOL fOpRedundant, + const RDP_RECT* bound) { + INT32 sx = 0, sy = 0; + INT32 dx, dy; rdpGlyph* glyph; rdpGraphics* graphics; rdpGlyphCache* glyph_cache; @@ -85,29 +88,56 @@ static BOOL update_process_glyph(rdpContext* context, const BYTE* data, if (!glyph) return FALSE; - if (glyph != NULL) + dx = glyph->x + *x; + dy = glyph->y + *y; + + if (dx < bound->x) { - if (!glyph->Draw(context, glyph, glyph->x + *x, glyph->y + *y, fOpRedundant)) - return FALSE; + sx = bound->x - dx; + dx = bound->x; + } - if (flAccel & SO_CHAR_INC_EQUAL_BM_BASE) - *x += glyph->cx; + if (dy < bound->y) + { + sy = bound->y - dy; + dy = bound->y; } + if ((dx <= (bound->x + bound->width)) && (dy <= (bound->y + bound->height))) + { + INT32 dw = glyph->cx - sx; + INT32 dh = glyph->cy - sy; + + if ((dw + dx) > (bound->x + bound->width)) + dw = (bound->x + bound->width) - (dw + dx); + + if ((dh + dy) > (bound->y + bound->height)) + dh = (bound->y + bound->height) - (dh + dy); + + if ((dh > 0) && (dw > 0)) + { + if (!glyph->Draw(context, glyph, dx, dy, dw, dh, sx, sy, fOpRedundant)) + return FALSE; + } + } + + if (flAccel & SO_CHAR_INC_EQUAL_BM_BASE) + *x += glyph->cx; + return TRUE; } static BOOL update_process_glyph_fragments(rdpContext* context, - const BYTE* data, - UINT32 length, UINT32 cacheId, - UINT32 ulCharInc, UINT32 flAccel, - UINT32 bgcolor, UINT32 fgcolor, - INT32 x, INT32 y, - INT32 bkX, INT32 bkY, - INT32 bkWidth, INT32 bkHeight, - INT32 opX, INT32 opY, - INT32 opWidth, INT32 opHeight, - BOOL fOpRedundant) + const BYTE* data, + UINT32 length, UINT32 cacheId, + UINT32 ulCharInc, UINT32 flAccel, + UINT32 bgcolor, UINT32 fgcolor, + INT32 x, INT32 y, + INT32 bkX, INT32 bkY, + INT32 bkWidth, INT32 bkHeight, + INT32 opX, INT32 opY, + INT32 opWidth, INT32 opHeight, + BOOL fOpRedundant) { UINT32 n; UINT32 id; @@ -117,6 +147,7 @@ static BOOL update_process_glyph_fragments(rdpContext* context, rdpGraphics* graphics; rdpGlyphCache* glyph_cache; rdpGlyph* glyph; + RDP_RECT bound; if (!context || !data || !context->graphics || !context->cache || !context->cache->glyph) @@ -129,6 +160,44 @@ static BOOL update_process_glyph_fragments(rdpContext* context, if (!glyph) return FALSE; + /* Limit op rectangle to vislble screen. */ + if (opX < 0) + { + opWidth += opX; + opX = 0; + } + + if (opY < 0) + { + opHeight += opY; + opY = 0; + } + + if (opWidth < 0) + opWidth = 0; + + if (opHeight < 0) + opHeight = 0; + + /* Limit bk rectangle to vislble screen. */ + if (bkX < 0) + { + bkWidth += bkX; + bkX = 0; + } + + if (bkY < 0) + { + bkHeight += bkY; + bkY = 0; + } + + if (bkWidth < 0) + bkWidth = 0; + + if (bkHeight < 0) + bkHeight = 0; + if (opX + opWidth > context->settings->DesktopWidth) { /** @@ -143,8 +212,27 @@ static BOOL update_process_glyph_fragments(rdpContext* context, opWidth = context->settings->DesktopWidth - opX; } + if (bkX + bkWidth > context->settings->DesktopWidth) + { + /** + * Some Microsoft servers send erroneous high values close to the + * sint16 maximum in the OpRight field of the GlyphIndex, FastIndex and + * FastGlyph drawing orders, probably a result of applications trying to + * clear the text line to the very right end. + * One example where this can be seen is typing in notepad.exe within + * a RDP session to Windows XP Professional SP3. + * This workaround prevents resulting problems in the UI callbacks. + */ + bkWidth = context->settings->DesktopWidth - bkX; + } + + bound.x = bkX; + bound.y = bkY; + bound.width = bkWidth; + bound.height = bkHeight; + if (!glyph->BeginDraw(context, opX, opY, opWidth, opHeight, bgcolor, fgcolor, - fOpRedundant)) + fOpRedundant)) return FALSE; while (index < length) @@ -155,54 +243,40 @@ static BOOL update_process_glyph_fragments(rdpContext* context, { case GLYPH_FRAGMENT_USE: if (index + 1 > length) - { - /* at least one byte need to follow */ - index = length = 0; - break; - } + return FALSE; id = data[index++]; fragments = (BYTE*) glyph_cache_fragment_get(glyph_cache, id, &size); - if (fragments != NULL) + if (fragments == NULL) + return FALSE; + + for (n = 0; n < size;) { - for (n = 0; n < size;) - { - const UINT32 fop = fragments[n++]; - n = update_glyph_offset(fragments, n, &x, &y, ulCharInc, flAccel); - - if (!update_process_glyph(context, fragments, fop, &x, &y, cacheId, - flAccel, fOpRedundant)) - return FALSE; - } + const UINT32 fop = fragments[n++]; + n = update_glyph_offset(fragments, n, &x, &y, ulCharInc, flAccel); + + if (!update_process_glyph(context, fragments, fop, &x, &y, cacheId, + flAccel, fOpRedundant, &bound)) + return FALSE; } break; case GLYPH_FRAGMENT_ADD: if (index + 2 > length) - { - /* at least two bytes need to follow */ - index = length = 0; - break; - } + return FALSE; id = data[index++]; size = data[index++]; - fragments = (BYTE*) malloc(size); - - if (!fragments) - return FALSE; - - CopyMemory(fragments, data, size); - glyph_cache_fragment_put(glyph_cache, id, size, fragments); + glyph_cache_fragment_put(glyph_cache, id, size, data); break; default: index = update_glyph_offset(data, index, &x, &y, ulCharInc, flAccel); if (!update_process_glyph(context, data, op, &x, &y, cacheId, flAccel, - fOpRedundant)) + fOpRedundant, &bound)) return FALSE; break; @@ -213,7 +287,7 @@ static BOOL update_process_glyph_fragments(rdpContext* context, } static BOOL update_gdi_glyph_index(rdpContext* context, - GLYPH_INDEX_ORDER* glyphIndex) + GLYPH_INDEX_ORDER* glyphIndex) { rdpGlyphCache* glyph_cache; INT32 bkWidth = 0, bkHeight = 0, opWidth = 0, opHeight = 0; @@ -236,16 +310,16 @@ static BOOL update_gdi_glyph_index(rdpContext* context, opHeight = glyphIndex->opBottom - glyphIndex->opTop + 1; return update_process_glyph_fragments(context, glyphIndex->data, - glyphIndex->cbData, - glyphIndex->cacheId, glyphIndex->ulCharInc, glyphIndex->flAccel, - glyphIndex->backColor, glyphIndex->foreColor, glyphIndex->x, glyphIndex->y, - glyphIndex->bkLeft, glyphIndex->bkTop, bkWidth, bkHeight, - glyphIndex->opLeft, glyphIndex->opTop, opWidth, opHeight, - glyphIndex->fOpRedundant); + glyphIndex->cbData, + glyphIndex->cacheId, glyphIndex->ulCharInc, glyphIndex->flAccel, + glyphIndex->backColor, glyphIndex->foreColor, glyphIndex->x, glyphIndex->y, + glyphIndex->bkLeft, glyphIndex->bkTop, bkWidth, bkHeight, + glyphIndex->opLeft, glyphIndex->opTop, opWidth, opHeight, + glyphIndex->fOpRedundant); } static BOOL update_gdi_fast_index(rdpContext* context, - const FAST_INDEX_ORDER* fastIndex) + const FAST_INDEX_ORDER* fastIndex) { INT32 x, y; INT32 opLeft, opTop; @@ -313,15 +387,15 @@ static BOOL update_gdi_fast_index(rdpContext* context, 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, bkWidth, bkHeight, - opLeft, opTop, opWidth, opHeight, FALSE); + fastIndex->cbData, + fastIndex->cacheId, fastIndex->ulCharInc, fastIndex->flAccel, + fastIndex->backColor, fastIndex->foreColor, x, y, + fastIndex->bkLeft, fastIndex->bkTop, bkWidth, bkHeight, + opLeft, opTop, opWidth, opHeight, FALSE); } static BOOL update_gdi_fast_glyph(rdpContext* context, - const FAST_GLYPH_ORDER* fastGlyph) + const FAST_GLYPH_ORDER* fastGlyph) { INT32 x, y; BYTE text_data[2]; @@ -385,13 +459,18 @@ static BOOL update_gdi_fast_glyph(rdpContext* context, return FALSE; glyph = Glyph_Alloc(context, glyphData->x, glyphData->y, glyphData->cx, - glyphData->cy, - glyphData->cb, glyphData->aj); + glyphData->cy, + glyphData->cb, glyphData->aj); if (!glyph) return FALSE; - glyph_cache_put(cache->glyph, fastGlyph->cacheId, fastGlyph->data[0], glyph); + if (!glyph_cache_put(cache->glyph, fastGlyph->cacheId, fastGlyph->data[0], + glyph)) + { + glyph->Free(context, glyph); + return FALSE; + } } text_data[0] = fastGlyph->data[0]; @@ -410,15 +489,15 @@ static BOOL update_gdi_fast_glyph(rdpContext* context, 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, - bkWidth, bkHeight, opLeft, opTop, - opWidth, opHeight, FALSE); + fastGlyph->cacheId, fastGlyph->ulCharInc, fastGlyph->flAccel, + fastGlyph->backColor, fastGlyph->foreColor, x, y, + fastGlyph->bkLeft, fastGlyph->bkTop, + bkWidth, bkHeight, opLeft, opTop, + opWidth, opHeight, FALSE); } static BOOL update_gdi_cache_glyph(rdpContext* context, - const CACHE_GLYPH_ORDER* cacheGlyph) + const CACHE_GLYPH_ORDER* cacheGlyph) { UINT32 i; rdpCache* cache; @@ -437,22 +516,26 @@ static BOOL update_gdi_cache_glyph(rdpContext* context, return FALSE; if (!(glyph = Glyph_Alloc(context, glyph_data->x, - glyph_data->y, - glyph_data->cx, - glyph_data->cy, - glyph_data->cb, - glyph_data->aj))) + glyph_data->y, + glyph_data->cx, + glyph_data->cy, + glyph_data->cb, + glyph_data->aj))) return FALSE; - glyph_cache_put(cache->glyph, cacheGlyph->cacheId, glyph_data->cacheIndex, - glyph); + if (!glyph_cache_put(cache->glyph, cacheGlyph->cacheId, glyph_data->cacheIndex, + glyph)) + { + glyph->Free(context, glyph); + return FALSE; + } } return TRUE; } static BOOL update_gdi_cache_glyph_v2(rdpContext* context, - const CACHE_GLYPH_V2_ORDER* cacheGlyphV2) + const CACHE_GLYPH_V2_ORDER* cacheGlyphV2) { UINT32 i; rdpCache* cache; @@ -471,17 +554,21 @@ static BOOL update_gdi_cache_glyph_v2(rdpContext* context, return FALSE; glyph = Glyph_Alloc(context, glyphData->x, - glyphData->y, - glyphData->cx, - glyphData->cy, - glyphData->cb, - glyphData->aj); + glyphData->y, + glyphData->cx, + glyphData->cy, + glyphData->cb, + glyphData->aj); if (!glyph) return FALSE; - glyph_cache_put(cache->glyph, cacheGlyphV2->cacheId, glyphData->cacheIndex, - glyph); + if (!glyph_cache_put(cache->glyph, cacheGlyphV2->cacheId, glyphData->cacheIndex, + glyph)) + { + glyph->Free(context, glyph); + return FALSE; + } } return TRUE; @@ -491,7 +578,7 @@ rdpGlyph* glyph_cache_get(rdpGlyphCache* glyphCache, UINT32 id, UINT32 index) { rdpGlyph* glyph; WLog_Print(glyphCache->log, WLOG_DEBUG, "GlyphCacheGet: id: %d index: %d", id, - index); + index); if (id > 9) { @@ -514,7 +601,7 @@ rdpGlyph* glyph_cache_get(rdpGlyphCache* glyphCache, UINT32 id, UINT32 index) } BOOL glyph_cache_put(rdpGlyphCache* glyphCache, UINT32 id, UINT32 index, - rdpGlyph* glyph) + rdpGlyph* glyph) { rdpGlyph* prevGlyph; @@ -531,7 +618,7 @@ BOOL glyph_cache_put(rdpGlyphCache* glyphCache, UINT32 id, UINT32 index, } WLog_Print(glyphCache->log, WLOG_DEBUG, "GlyphCachePut: id: %d index: %d", id, - index); + index); prevGlyph = glyphCache->glyphCache[id].entries[index]; if (prevGlyph) @@ -541,8 +628,8 @@ BOOL glyph_cache_put(rdpGlyphCache* glyphCache, UINT32 id, UINT32 index, return TRUE; } -void* glyph_cache_fragment_get(rdpGlyphCache* glyphCache, UINT32 index, - UINT32* size) +const void* glyph_cache_fragment_get(rdpGlyphCache* glyphCache, UINT32 index, + UINT32* size) { void* fragment; @@ -555,7 +642,7 @@ void* glyph_cache_fragment_get(rdpGlyphCache* glyphCache, UINT32 index, fragment = glyphCache->fragCache.entries[index].fragment; *size = (BYTE) glyphCache->fragCache.entries[index].size; WLog_Print(glyphCache->log, WLOG_DEBUG, - "GlyphCacheFragmentGet: index: %d size: %d", index, *size); + "GlyphCacheFragmentGet: index: %d size: %d", index, *size); if (!fragment) WLog_ERR(TAG, "invalid glyph fragment at index:%d", index); @@ -563,23 +650,31 @@ void* glyph_cache_fragment_get(rdpGlyphCache* glyphCache, UINT32 index, return fragment; } -void glyph_cache_fragment_put(rdpGlyphCache* glyphCache, UINT32 index, - UINT32 size, void* fragment) +BOOL glyph_cache_fragment_put(rdpGlyphCache* glyphCache, UINT32 index, + UINT32 size, const void* fragment) { void* prevFragment; + void* copy; if (index > 255) { WLog_ERR(TAG, "invalid glyph cache fragment index: %d", index); - return; + return FALSE; } + copy = malloc(size); + + if (!copy) + return FALSE; + WLog_Print(glyphCache->log, WLOG_DEBUG, - "GlyphCacheFragmentPut: index: %d size: %d", index, size); + "GlyphCacheFragmentPut: index: %d size: %d", index, size); + CopyMemory(copy, fragment, size); prevFragment = glyphCache->fragCache.entries[index].fragment; - glyphCache->fragCache.entries[index].fragment = fragment; + glyphCache->fragCache.entries[index].fragment = copy; glyphCache->fragCache.entries[index].size = size; free(prevFragment); + return TRUE; } void glyph_cache_register_callbacks(rdpUpdate* update) @@ -610,7 +705,7 @@ rdpGlyphCache* glyph_cache_new(rdpSettings* settings) glyphCache->glyphCache[i].maxCellSize = settings->GlyphCache[i].cacheMaximumCellSize; glyphCache->glyphCache[i].entries = (rdpGlyph**) calloc( - glyphCache->glyphCache[i].number, sizeof(rdpGlyph*)); + glyphCache->glyphCache[i].number, sizeof(rdpGlyph*)); } glyphCache->fragCache.entries = calloc(256, sizeof(FRAGMENT_CACHE_ENTRY)); diff --git a/libfreerdp/gdi/graphics.c b/libfreerdp/gdi/graphics.c index 0bc4070..c4333fd 100644 --- a/libfreerdp/gdi/graphics.c +++ b/libfreerdp/gdi/graphics.c @@ -255,7 +255,7 @@ static void gdi_Glyph_Free(rdpContext* context, rdpGlyph* glyph) } static BOOL gdi_Glyph_Draw(rdpContext* context, const rdpGlyph* glyph, UINT32 x, - UINT32 y, BOOL fOpRedundant) + UINT32 y, UINT32 w, UINT32 h, UINT32 sx, UINT32 sy, BOOL fOpRedundant) { gdiGlyph* gdi_glyph; rdpGdi* gdi; @@ -267,14 +267,42 @@ static BOOL gdi_Glyph_Draw(rdpContext* context, const rdpGlyph* glyph, UINT32 x, gdi = context->gdi; gdi_glyph = (gdiGlyph*) glyph; + + if (!fOpRedundant && 0) + { + GDI_RECT rect = { 0 }; + + if (x > 0) + rect.left = x; + + if (y > 0) + rect.top = y; + + if (x + w > 0) + rect.right = x + w - 1; + + if (y + h > 0) + rect.bottom = y + h - 1; + + if ((rect.left < rect.right) && (rect.top < rect.bottom)) + { + brush = gdi_CreateSolidBrush(gdi->drawing->hdc->bkColor); + + if (!brush) + return FALSE; + + gdi_FillRect(gdi->drawing->hdc, &rect, brush); + gdi_DeleteObject((HGDIOBJECT)brush); + } + } + 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, + rc = gdi_BitBlt(gdi->drawing->hdc, x, y, w, h, gdi_glyph->hdc, sx, sy, GDI_GLYPH_ORDER, &context->gdi->palette); gdi_DeleteObject((HGDIOBJECT)brush); return rc; @@ -303,7 +331,7 @@ static BOOL gdi_Glyph_BeginDraw(rdpContext* context, UINT32 x, UINT32 y, gdi_SetTextColor(gdi->drawing->hdc, bgcolor); gdi_SetBkColor(gdi->drawing->hdc, fgcolor); - if (!fOpRedundant) + if (1) { GDI_RECT rect = { 0 }; HGDI_BRUSH brush = gdi_CreateSolidBrush(fgcolor); @@ -317,13 +345,12 @@ static BOOL gdi_Glyph_BeginDraw(rdpContext* context, UINT32 x, UINT32 y, if (y > 0) rect.top = y; - if (x + width > 0) - rect.right = x + width - 1; + rect.right = x + width - 1; + rect.bottom = y + height - 1; - if (y + height > 0) - rect.bottom = y + height - 1; + if ((x + width > rect.left) && (y + height > rect.top)) + gdi_FillRect(gdi->drawing->hdc, &rect, brush); - gdi_FillRect(gdi->drawing->hdc, &rect, brush); gdi_DeleteObject((HGDIOBJECT)brush); } -- 2.7.4