From c8fc2cde53ef7aa011ec7c47e7fc5486de0651f5 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Wed, 1 Feb 2012 01:27:43 +0000 Subject: [PATCH] sna: Fill extents for ImageGlyphs The spec says to fill the characters boxes, which is what the hardware does. The implementation fills the extents instead. rxvt expects the former, emacs the latter. Overdraw is a nuisance, but less than leaving glyphs behind... Reported-by: walch.martin@web.de Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=45438 Signed-off-by: Chris Wilson --- src/sna/sna.h | 3 +- src/sna/sna_accel.c | 71 ++++++++++++++++++++++++++++++++++++--------- 2 files changed, 59 insertions(+), 15 deletions(-) diff --git a/src/sna/sna.h b/src/sna/sna.h index a0ea54ff..9df8cfdc 100644 --- a/src/sna/sna.h +++ b/src/sna/sna.h @@ -359,7 +359,8 @@ to_sna_from_kgem(struct kgem *kgem) #define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0])) #endif #define ALIGN(i,m) (((i) + (m) - 1) & ~((m) - 1)) -#define MIN(a,b) ((a) < (b) ? (a) : (b)) +#define MIN(a,b) ((a) <= (b) ? (a) : (b)) +#define MAX(a,b) ((a) >= (b) ? (a) : (b)) extern xf86CrtcPtr sna_covering_crtc(ScrnInfoPtr scrn, const BoxRec *box, diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c index 4148bdb4..40748ec4 100644 --- a/src/sna/sna_accel.c +++ b/src/sna/sna_accel.c @@ -10011,6 +10011,11 @@ sna_glyph_blt(DrawablePtr drawable, GCPtr gc, extents = REGION_RECTS(clip); last_extents = extents + REGION_NUM_RECTS(clip); + if (bg != -1) /* emulate miImageGlyphBlt */ + sna_blt_fill_boxes(sna, GXcopy, + bo, drawable->bitsPerPixel, + bg, extents, REGION_NUM_RECTS(clip)); + kgem_set_mode(&sna->kgem, KGEM_BLT); if (!kgem_check_batch(&sna->kgem, 16) || !kgem_check_bo_fenced(&sna->kgem, bo, NULL) || @@ -10174,6 +10179,8 @@ sna_glyph_extents(FontPtr font, extents->overallWidth += p->metrics.characterWidth; } + + assert(extents->overallWidth > 0); } static bool sna_set_glyph(CharInfoPtr in, CharInfoPtr out) @@ -10458,10 +10465,17 @@ sna_image_text8(DrawablePtr drawable, GCPtr gc, return; sna_glyph_extents(gc->font, info, n, &extents); - region.extents.x1 = x + extents.overallLeft; - region.extents.y1 = y - extents.overallAscent; - region.extents.x2 = x + extents.overallRight; - region.extents.y2 = y + extents.overallDescent; + region.extents.x1 = x + MIN(0, extents.overallLeft); + region.extents.y1 = y - extents.fontAscent; + region.extents.x2 = x + MAX(extents.overallWidth, extents.overallRight); + region.extents.y2 = y + extents.fontDescent; + + DBG(("%s: count=%ld/%d, extents=(left=%d, right=%d, width=%d, ascent=%d, descent=%d), box=(%d, %d), (%d, %d)\n", + __FUNCTION__, n, count, + extents.overallLeft, extents.overallRight, extents.overallWidth, + extents.fontAscent, extents.fontDescent, + region.extents.x1, region.extents.y1, + region.extents.x2, region.extents.y2)); translate_box(®ion.extents, drawable); clip_box(®ion.extents, gc); @@ -10473,6 +10487,11 @@ sna_image_text8(DrawablePtr drawable, GCPtr gc, if (!RegionNotEmpty(®ion)) return; + DBG(("%s: clipped extents (%d, %d), (%d, %d)\n", + __FUNCTION__, + region.extents.x1, region.extents.y1, + region.extents.x2, region.extents.y2)); + if (FORCE_FALLBACK) goto force_fallback; @@ -10535,10 +10554,17 @@ sna_image_text16(DrawablePtr drawable, GCPtr gc, return; sna_glyph_extents(gc->font, info, n, &extents); - region.extents.x1 = x + extents.overallLeft; - region.extents.y1 = y - extents.overallAscent; - region.extents.x2 = x + extents.overallRight; - region.extents.y2 = y + extents.overallDescent; + region.extents.x1 = x + MIN(0, extents.overallLeft); + region.extents.y1 = y - extents.fontAscent; + region.extents.x2 = x + MAX(extents.overallWidth, extents.overallRight); + region.extents.y2 = y + extents.fontDescent; + + DBG(("%s: count=%ld/%d, extents=(left=%d, right=%d, width=%d, ascent=%d, descent=%d), box=(%d, %d), (%d, %d)\n", + __FUNCTION__, n, count, + extents.overallLeft, extents.overallRight, extents.overallWidth, + extents.fontAscent, extents.fontDescent, + region.extents.x1, region.extents.y1, + region.extents.x2, region.extents.y2)); translate_box(®ion.extents, drawable); clip_box(®ion.extents, gc); @@ -10550,6 +10576,11 @@ sna_image_text16(DrawablePtr drawable, GCPtr gc, if (!RegionNotEmpty(®ion)) return; + DBG(("%s: clipped extents (%d, %d), (%d, %d)\n", + __FUNCTION__, + region.extents.x1, region.extents.y1, + region.extents.x2, region.extents.y2)); + if (FORCE_FALLBACK) goto force_fallback; @@ -10625,6 +10656,11 @@ sna_reversed_glyph_blt(DrawablePtr drawable, GCPtr gc, extents = REGION_RECTS(clip); last_extents = extents + REGION_NUM_RECTS(clip); + if (bg != -1) /* emulate miImageGlyphBlt */ + sna_blt_fill_boxes(sna, GXcopy, + bo, drawable->bitsPerPixel, + bg, extents, REGION_NUM_RECTS(clip)); + kgem_set_mode(&sna->kgem, KGEM_BLT); if (!kgem_check_batch(&sna->kgem, 16) || !kgem_check_bo_fenced(&sna->kgem, bo, NULL) || @@ -10775,11 +10811,18 @@ sna_image_glyph(DrawablePtr drawable, GCPtr gc, if (n == 0) return; - QueryGlyphExtents(gc->font, info, n, &extents); - region.extents.x1 = x + extents.overallLeft; - region.extents.y1 = y - extents.overallAscent; - region.extents.x2 = x + extents.overallRight; - region.extents.y2 = y + extents.overallDescent; + sna_glyph_extents(gc->font, info, n, &extents); + region.extents.x1 = x + MIN(0, extents.overallLeft); + region.extents.y1 = y - extents.fontAscent; + region.extents.x2 = x + MAX(extents.overallWidth, extents.overallRight); + region.extents.y2 = y + extents.fontDescent; + + DBG(("%s: count=%d, extents=(left=%d, right=%d, width=%d, ascent=%d, descent=%d), box=(%d, %d), (%d, %d)\n", + __FUNCTION__, n, + extents.overallLeft, extents.overallRight, extents.overallWidth, + extents.fontAscent, extents.fontDescent, + region.extents.x1, region.extents.y1, + region.extents.x2, region.extents.y2)); translate_box(®ion.extents, drawable); clip_box(®ion.extents, gc); @@ -10847,7 +10890,7 @@ sna_poly_glyph(DrawablePtr drawable, GCPtr gc, if (n == 0) return; - QueryGlyphExtents(gc->font, info, n, &extents); + sna_glyph_extents(gc->font, info, n, &extents); region.extents.x1 = x + extents.overallLeft; region.extents.y1 = y - extents.overallAscent; region.extents.x2 = x + extents.overallRight;