1 Bug 29092 - Fix glyphs rendering for cairo-qpainter-surface
2 diff --git a/src/cairo-qt-surface.cpp b/src/cairo-qt-surface.cpp
3 index 2ac06ef..5b61b42 100644
4 --- a/src/cairo-qt-surface.cpp
5 +++ b/src/cairo-qt-surface.cpp
7 #include "cairo-surface-clipper-private.h"
8 #include "cairo-types-private.h"
10 +#include "cairo-ft.h"
16 #include <QtGui/QWidget>
17 #include <QtGui/QX11Info>
18 +#include <QtCore/QVarLengthArray>
20 -#if CAIRO_HAS_XLIB_XRENDER_SURFACE
21 -#include "cairo-xlib.h"
22 -#include "cairo-xlib-xrender.h"
27 +#if (QT_VERSION >= QT_VERSION_CHECK(4, 7, 0)) || defined(QT_GLYPHS_API_BACKPORT)
28 +extern void qt_draw_glyphs(QPainter *, const quint32 *glyphs, const QPointF *positions, int count);
32 @@ -118,15 +115,6 @@ struct cairo_qt_surface_t {
34 cairo_bool_t supports_porter_duff;
36 -#if defined(Q_WS_X11) && CAIRO_HAS_XLIB_XRENDER_SURFACE
37 - /* temporary, so that we can share the xlib surface's glyphs code */
38 - bool xlib_has_clipping;
39 - cairo_surface_t *xlib_equiv;
40 - QRect xlib_clip_bounds;
41 - int xlib_clip_serial;
42 - QPoint redir_offset;
47 /* The pixmap/image constructors will store their objects here */
48 @@ -145,11 +133,6 @@ struct cairo_qt_surface_t {
50 static cairo_bool_t _qpixmaps_have_no_alpha = FALSE;
52 -#if defined(Q_WS_X11) && CAIRO_HAS_XLIB_XRENDER_SURFACE
53 -slim_hidden_proto (cairo_xlib_surface_create);
54 -slim_hidden_proto (cairo_xlib_surface_create_with_xrender_format);
60 @@ -498,11 +481,6 @@ _cairo_qt_surface_finish (void *abstract_surface)
62 _cairo_surface_clipper_reset (&qs->clipper);
64 -#if defined(Q_WS_X11) && CAIRO_HAS_XLIB_XRENDER_SURFACE
66 - cairo_surface_destroy (qs->xlib_equiv);
72 @@ -1392,33 +1370,40 @@ _cairo_qt_surface_show_glyphs (void *abstract_surface,
74 int *remaining_glyphs)
76 +#if (QT_VERSION >= QT_VERSION_CHECK(4, 7, 0)) || defined(QT_GLYPHS_API_BACKPORT)
77 cairo_qt_surface_t *qs = (cairo_qt_surface_t *) abstract_surface;
79 -#if defined(Q_WS_X11) && CAIRO_HAS_XLIB_XRENDER_SURFACE
80 - /* If we have an equivalent X surface, let the xlib surface handle this
81 - * until we figure out how to do this natively with Qt.
83 - if (qs->xlib_equiv) {
84 - D(fprintf(stderr, "q[%p] show_glyphs (x11 equiv) op:%s nglyphs: %d\n", abstract_surface, _opstr(op), num_glyphs));
86 - for (int i = 0; i < num_glyphs; i++) {
87 - glyphs[i].x -= qs->redir_offset.x();
88 - glyphs[i].y -= qs->redir_offset.y();
91 - return (cairo_int_status_t)
92 - _cairo_surface_show_text_glyphs (qs->xlib_equiv,
97 - (cairo_text_cluster_flags_t) 0,
100 + // pick out the colour to use from the cairo source
101 + cairo_solid_pattern_t *solid = (cairo_solid_pattern_t*) source;
102 + cairo_scaled_glyph_t* glyph;
103 + // documentation says you have to freeze the cache, but I don't believe it
104 + _cairo_scaled_font_freeze_cache(scaled_font);
106 + QColor tempColour(solid->color.red * 255, solid->color.green * 255, solid->color.blue * 255);
107 + QVarLengthArray<QPointF> positions(num_glyphs);
108 + QVarLengthArray<unsigned int> glyphss(num_glyphs);
109 + FT_Face face = cairo_ft_scaled_font_lock_face (scaled_font);
110 + const FT_Size_Metrics& ftMetrics = face->size->metrics;
111 + QFont font(face->family_name);
112 + font.setStyleStrategy(QFont::NoFontMerging);
113 + font.setBold(face->style_flags & FT_STYLE_FLAG_BOLD);
114 + font.setItalic(face->style_flags & FT_STYLE_FLAG_ITALIC);
115 + font.setKerning(face->face_flags & FT_FACE_FLAG_KERNING);
116 + font.setPixelSize(ftMetrics.y_ppem);
117 + cairo_ft_scaled_font_unlock_face(scaled_font);
118 + qs->p->setFont(font);
119 + qs->p->setPen(tempColour);
120 + for (int currentGlyph = 0; currentGlyph < num_glyphs; currentGlyph++) {
121 + positions[currentGlyph].setX(glyphs[currentGlyph].x);
122 + positions[currentGlyph].setY(glyphs[currentGlyph].y);
123 + glyphss[currentGlyph] = glyphs[currentGlyph].index;
127 + qt_draw_glyphs(qs->p, glyphss.data(), positions.data(), num_glyphs);
128 + _cairo_scaled_font_thaw_cache(scaled_font);
129 + return CAIRO_INT_STATUS_SUCCESS;
131 return CAIRO_INT_STATUS_UNSUPPORTED;
135 static cairo_int_status_t
136 @@ -1555,24 +1540,6 @@ _cairo_qt_surface_composite (cairo_operator_t op,
139 static cairo_status_t
140 -_cairo_qt_surface_flush (void *abstract_surface)
142 - cairo_qt_surface_t *qs = (cairo_qt_surface_t *) abstract_surface;
145 - return CAIRO_STATUS_SUCCESS;
147 - if (qs->image || qs->pixmap) {
149 - qs->p->begin (qs->p->device ());
154 - return CAIRO_STATUS_SUCCESS;
157 -static cairo_status_t
158 _cairo_qt_surface_mark_dirty (void *abstract_surface,
160 int width, int height)
161 @@ -1609,7 +1576,7 @@ static const cairo_surface_backend_t cairo_qt_surface_backend = {
162 _cairo_qt_surface_get_extents,
163 NULL, /* old_show_glyphs */
164 NULL, /* get_font_options */
165 - _cairo_qt_surface_flush,
167 _cairo_qt_surface_mark_dirty,
168 NULL, /* scaled_font_fini */
169 NULL, /* scaled_glyph_fini */
170 @@ -1629,64 +1596,6 @@ static const cairo_surface_backend_t cairo_qt_surface_backend = {
171 NULL, /* show_text_glyphs */
174 -#if defined(Q_WS_X11) && CAIRO_HAS_XLIB_XRENDER_SURFACE
175 -static cairo_surface_t *
176 -_cairo_qt_create_xlib_surface (cairo_qt_surface_t *qs)
181 - QPaintDevice *pd = qs->p->device();
186 - QPaintDevice *rpd = QPainter::redirected(pd, &offs);
189 - qs->redir_offset = offs;
192 - if (pd->devType() == QInternal::Widget) {
193 - QWidget *w = (QWidget*) pd;
194 - QX11Info xinfo = w->x11Info();
196 - return cairo_xlib_surface_create (xinfo.display(),
197 - (Drawable) w->handle (),
198 - (Visual *) xinfo.visual (),
199 - w->width (), w->height ());
200 - } else if (pd->devType() == QInternal::Pixmap) {
201 - QPixmap *pixmap = (QPixmap*) pd;
202 - QX11Info xinfo = pixmap->x11Info ();
203 - XRenderPictFormat *xrender_format;
206 - switch (pixmap->depth ()) {
208 - pict_format = PictStandardA1; break;
210 - pict_format = PictStandardA8; break;
212 - pict_format = PictStandardRGB24; break;
214 - ASSERT_NOT_REACHED;
216 - pict_format = PictStandardARGB32; break;
218 - xrender_format = XRenderFindStandardFormat (xinfo.display (),
221 - return cairo_xlib_surface_create_with_xrender_format (xinfo.display(),
222 - (Drawable) pixmap->handle (),
223 - ScreenOfDisplay (xinfo.display (),
226 - pixmap->width (), pixmap->height ());
233 cairo_qt_surface_create (QPainter *painter)
235 @@ -1717,10 +1626,6 @@ cairo_qt_surface_create (QPainter *painter)
237 qs->window = painter->window();
239 -#if defined(Q_WS_X11) && CAIRO_HAS_XLIB_XRENDER_SURFACE
240 - qs->xlib_equiv = _cairo_qt_create_xlib_surface (qs);
243 D(fprintf(stderr, "qpainter_surface_create: window: [%d %d %d %d] pd:%d\n",
244 qs->window.x(), qs->window.y(), qs->window.width(), qs->window.height(),
245 qs->supports_porter_duff));
246 @@ -1819,10 +1724,6 @@ cairo_qt_surface_create_with_qpixmap (cairo_content_t content,
248 qs->window = QRect(0, 0, width, height);
250 -#if defined(Q_WS_X11) && CAIRO_HAS_XLIB_XRENDER_SURFACE
251 - qs->xlib_equiv = _cairo_qt_create_xlib_surface (qs);
254 D(fprintf(stderr, "qpainter_surface_create: qpixmap: [%d %d %d %d] pd:%d\n",
255 qs->window.x(), qs->window.y(), qs->window.width(), qs->window.height(),
256 qs->supports_porter_duff));