xserver-multidpi/fb
Peter Harris 6e31a3e4b5 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;
}

(cherry picked from commit 983e30361f)
2014-05-31 17:50:34 -07:00
..
Makefile.am fb: Remove hw/xfree86/ from includes 2011-02-08 12:41:13 -05:00
fb.h fb: Remove unused compatibility wrappers 2013-09-10 13:29:21 -04:00
fb24_32.c Introduce a consistent coding style 2012-03-21 13:54:42 -07:00
fb24_32.h Introduce a consistent coding style 2012-03-21 13:54:42 -07:00
fballpriv.c Use new screen-specific privates for fb window and gc privates 2012-07-05 13:40:18 -07:00
fbarc.c Introduce a consistent coding style 2012-03-21 13:54:42 -07:00
fbbits.c Introduce a consistent coding style 2012-03-21 13:54:42 -07:00
fbbits.h Introduce a consistent coding style 2012-03-21 13:54:42 -07:00
fbblt.c fb: fix shadow warnings 2012-11-05 13:25:01 -06:00
fbbltone.c fb: fix shadow warnings 2012-11-05 13:25:01 -06:00
fbcmap_mi.c Introduce a consistent coding style 2012-03-21 13:54:42 -07:00
fbcopy.c fb: Remove unused compatibility wrappers 2013-09-10 13:29:21 -04:00
fbfill.c Introduce a consistent coding style 2012-03-21 13:54:42 -07:00
fbfillrect.c Introduce a consistent coding style 2012-03-21 13:54:42 -07:00
fbfillsp.c Introduce a consistent coding style 2012-03-21 13:54:42 -07:00
fbgc.c Fix formatting of address operators 2012-12-05 18:09:48 -06:00
fbgetsp.c Introduce a consistent coding style 2012-03-21 13:54:42 -07:00
fbglyph.c Introduce a consistent coding style 2012-03-21 13:54:42 -07:00
fbimage.c Introduce a consistent coding style 2012-03-21 13:54:42 -07:00
fbline.c Introduce a consistent coding style 2012-03-21 13:54:42 -07:00
fboverlay.c Use new screen-specific privates for fb window and gc privates 2012-07-05 13:40:18 -07:00
fboverlay.h api: rework the X server driver API to avoid global arrays. 2012-06-05 13:22:18 +01:00
fbpict.c fb: Fix origin of source picture in fbGlyphs 2014-05-31 17:50:34 -07:00
fbpict.h Introduce a consistent coding style 2012-03-21 13:54:42 -07:00
fbpixmap.c dix: allow pixmap dirty helper to be used for non-shared pixmaps 2013-04-30 10:10:31 +10:00
fbpoint.c Introduce a consistent coding style 2012-03-21 13:54:42 -07:00
fbpush.c Introduce a consistent coding style 2012-03-21 13:54:42 -07:00
fbrop.h Introduce a consistent coding style 2012-03-21 13:54:42 -07:00
fbscreen.c Use new pixman_glyph_cache_t API that will be in pixman 0.28.0 2012-10-25 11:37:50 -04:00
fbseg.c fb: reorder Bresenham error correction to avoid overshoot. 2012-08-14 12:14:25 -07:00
fbsetsp.c Introduce a consistent coding style 2012-03-21 13:54:42 -07:00
fbsolid.c Introduce a consistent coding style 2012-03-21 13:54:42 -07:00
fbstipple.c Introduce a consistent coding style 2012-03-21 13:54:42 -07:00
fbtile.c Introduce a consistent coding style 2012-03-21 13:54:42 -07:00
fbtrap.c Introduce a consistent coding style 2012-03-21 13:54:42 -07:00
fbutil.c Introduce a consistent coding style 2012-03-21 13:54:42 -07:00
fbwindow.c Use new screen-specific privates for fb window and gc privates 2012-07-05 13:40:18 -07:00
wfbrename.h fb: Rename wfbDestroyGlyphCache 2013-03-07 18:20:18 -08:00