summaryrefslogtreecommitdiff
path: root/fb
diff options
context:
space:
mode:
authorPeter Harris <pharris@opentext.com>2014-04-11 17:44:59 -0400
committerKeith Packard <keithp@keithp.com>2014-04-21 20:48:34 -0700
commit983e30361f49a67252d0b5d82630e70724d69dbf (patch)
tree6ceb981165d0a02926ac23f78e5ce93948c154e0 /fb
parent80a0b29c3b61ba9024bd0278ea8cc51686afe3f4 (diff)
fb: Fix origin of source picture in fbGlyphs
If a source picture doesn't repeat and a mask format is specified, the incorrect calulation of the origin of the glyphs caused the glyphs to not be drawn at all. Noticed when running gtk-demo from RHEL 6.5 and selecting "Rotated Text". Signed-off-by: Peter Harris <pharris@opentext.com> Reviewed-by: Keith Packard <keithp@keithp.com> Signed-off-by: Keith Packard <keithp@keithp.com> /* Test for this bug cc -std=c99 -o glyph glyph.c `pkg-config --cflags --libs xcb-render` */ // 16 x 16 pictfmt_a8 "glyph" static const char glyph[] = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0, 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0, 0, 0, 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0, 0, 0, 0, 0, 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0, 0, 0, 0, 0, 0, 0, 0xff, 0, 0, 0, 0, 0, 0, 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0, 0, 0, 0, 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0, 0, 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0, 0, 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0, 0, 0, 0, 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0, 0, 0, 0, 0, 0, 0xff, 0, 0, 0, 0, 0, 0, 0, 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0, 0, 0, 0, 0, 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0, 0, 0, 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0, 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, }; static struct { uint8_t len; uint8_t pad[3]; uint16_t deltax, deltay; uint8_t glyph; uint8_t pad2[3]; } elt = { len:1, glyph:1, deltax:WIN_SIZE/2 - GLYPH_SIZE/2, deltay:WIN_SIZE/2 - GLYPH_SIZE/2 }; int main(int argc, char *argv[]) { int screen; xcb_connection_t *c = xcb_connect(NULL, &screen); if (!c || xcb_connection_has_error(c)) { fprintf(stderr, "Cannot open default display \"%s\"\n", getenv("DISPLAY")); return EXIT_FAILURE; } // Find root window and depth const xcb_setup_t *setup = xcb_get_setup(c); if (screen >= setup->roots_len) screen = 0; xcb_screen_iterator_t si = xcb_setup_roots_iterator(setup); for (int i=0; i < screen; i++) xcb_screen_next(&si); xcb_window_t root = si.data->root; uint8_t depth = si.data->root_depth; xcb_visualid_t visual = si.data->root_visual; // Find picture formats xcb_render_query_pict_formats_reply_t *qpf; qpf = xcb_render_query_pict_formats_reply(c, xcb_render_query_pict_formats(c), NULL); if (!qpf) { fprintf(stderr, "Cannot query RENDER picture formats\n"); return EXIT_FAILURE; } xcb_render_pictformat_t fmt_a8 = 0; xcb_render_pictforminfo_iterator_t pfi = xcb_render_query_pict_formats_formats_iterator(qpf); for (int i = 0; i < xcb_render_query_pict_formats_formats_length(qpf); i++) { if (pfi.data->depth == 8 && pfi.data->type == XCB_RENDER_PICT_TYPE_DIRECT && pfi.data->direct.alpha_mask == 0xFF) { fmt_a8 = pfi.data->id; break; } xcb_render_pictforminfo_next(&pfi); } if (!fmt_a8) { fprintf(stderr, "Cannot find a8 RENDER picture format\n"); return EXIT_FAILURE; } xcb_render_pictformat_t fmt_visual = 0; xcb_render_pictscreen_iterator_t psi = xcb_render_query_pict_formats_screens_iterator(qpf); for (int i = 0; i < xcb_render_query_pict_formats_screens_length(qpf); i++) { xcb_render_pictdepth_iterator_t pdi = xcb_render_pictscreen_depths_iterator(psi.data); for (int j = 0; i < xcb_render_pictscreen_depths_length(psi.data); i++) { xcb_render_pictvisual_iterator_t pvi = xcb_render_pictdepth_visuals_iterator(pdi.data); for (int k = 0; k < xcb_render_pictdepth_visuals_length(pdi.data); i++) { if (pvi.data->visual == visual) { fmt_visual = pvi.data->format; goto found_visual; } xcb_render_pictvisual_next(&pvi); } xcb_render_pictdepth_next(&pdi); } xcb_render_pictscreen_next(&psi); } found_visual: if (!fmt_visual) { fprintf(stderr, "Cannot find visual RENDER picture format\n"); return EXIT_FAILURE; } xcb_render_glyphset_t glyphset = xcb_generate_id(c); xcb_render_create_glyph_set(c, glyphset, fmt_a8); uint32_t glyph_ids[] = {1}; xcb_render_add_glyphs(c, glyphset, 1, glyph_ids, &(xcb_render_glyphinfo_t){width:GLYPH_SIZE, height:GLYPH_SIZE}, sizeof(glyph), glyph); // Create window, pixmap, and gc xcb_window_t window = xcb_generate_id(c); uint32_t list[] = { si.data->black_pixel, XCB_EVENT_MASK_EXPOSURE }; xcb_create_window(c, XCB_COPY_FROM_PARENT, window, root, 0, 0, WIN_SIZE, WIN_SIZE, 0, XCB_WINDOW_CLASS_INPUT_OUTPUT, XCB_COPY_FROM_PARENT, XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK, list); xcb_map_window(c, window); xcb_render_picture_t winpic = xcb_generate_id(c); xcb_render_create_picture(c, winpic, window, fmt_visual, 0, NULL); xcb_pixmap_t pixmap = xcb_generate_id(c); xcb_create_pixmap(c, depth, pixmap, window, GLYPH_SIZE, GLYPH_SIZE); xcb_render_picture_t pixpic = xcb_generate_id(c); xcb_render_create_picture(c, pixpic, pixmap, fmt_visual, 0, NULL); xcb_render_fill_rectangles(c, XCB_RENDER_PICT_OP_SRC, pixpic, (xcb_render_color_t){green:0xFFFF, alpha:0xFFFF}, 1, &(xcb_rectangle_t){width:GLYPH_SIZE, height:GLYPH_SIZE} ); xcb_flush(c); for (xcb_generic_event_t *ev = xcb_wait_for_event(c); ev; ev = xcb_wait_for_event(c)) { int type = ev->response_type; free(ev); if (type == XCB_EXPOSE) { xcb_clear_area(c, 0, window, 0, 0, 0, 0); xcb_render_composite_glyphs_8(c, XCB_RENDER_PICT_OP_SRC, pixpic, winpic, fmt_a8, glyphset, 0, 0, sizeof(elt), (uint8_t *)&elt); xcb_flush(c); } } return EXIT_SUCCESS; }
Diffstat (limited to 'fb')
-rw-r--r--fb/fbpict.c2
1 files changed, 1 insertions, 1 deletions
diff --git a/fb/fbpict.c b/fb/fbpict.c
index c2ee8a552..21baf8950 100644
--- a/fb/fbpict.c
+++ b/fb/fbpict.c
@@ -191,7 +191,7 @@ fbGlyphs(CARD8 op,
pixman_glyph_get_extents(glyphCache, n_glyphs, pglyphs, &extents);
pixman_composite_glyphs(op, srcImage, dstImage, format,
- xSrc + srcXoff + xDst, ySrc + srcYoff + yDst,
+ xSrc + srcXoff + extents.x1 - xDst, ySrc + srcYoff + extents.y1 - yDst,
extents.x1, extents.y1,
extents.x1 + dstXoff, extents.y1 + dstYoff,
extents.x2 - extents.x1,