1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/gfx/cairo/cairo_qt_glyphs.patch Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,256 @@ 1.4 +Bug 29092 - Fix glyphs rendering for cairo-qpainter-surface 1.5 +diff --git a/src/cairo-qt-surface.cpp b/src/cairo-qt-surface.cpp 1.6 +index 2ac06ef..5b61b42 100644 1.7 +--- a/src/cairo-qt-surface.cpp 1.8 ++++ b/src/cairo-qt-surface.cpp 1.9 +@@ -45,6 +45,7 @@ 1.10 + #include "cairo-surface-clipper-private.h" 1.11 + #include "cairo-types-private.h" 1.12 + 1.13 ++#include "cairo-ft.h" 1.14 + #include "cairo-qt.h" 1.15 + 1.16 + #include <memory> 1.17 +@@ -58,14 +59,10 @@ 1.18 + #include <QtGui/QPen> 1.19 + #include <QtGui/QWidget> 1.20 + #include <QtGui/QX11Info> 1.21 ++#include <QtCore/QVarLengthArray> 1.22 + 1.23 +-#if CAIRO_HAS_XLIB_XRENDER_SURFACE 1.24 +-#include "cairo-xlib.h" 1.25 +-#include "cairo-xlib-xrender.h" 1.26 +-// I hate X 1.27 +-#undef Status 1.28 +-#undef CursorShape 1.29 +-#undef Bool 1.30 ++#if (QT_VERSION >= QT_VERSION_CHECK(4, 7, 0)) || defined(QT_GLYPHS_API_BACKPORT) 1.31 ++extern void qt_draw_glyphs(QPainter *, const quint32 *glyphs, const QPointF *positions, int count); 1.32 + #endif 1.33 + 1.34 + #include <sys/time.h> 1.35 +@@ -118,15 +115,6 @@ struct cairo_qt_surface_t { 1.36 + 1.37 + cairo_bool_t supports_porter_duff; 1.38 + 1.39 +-#if defined(Q_WS_X11) && CAIRO_HAS_XLIB_XRENDER_SURFACE 1.40 +- /* temporary, so that we can share the xlib surface's glyphs code */ 1.41 +- bool xlib_has_clipping; 1.42 +- cairo_surface_t *xlib_equiv; 1.43 +- QRect xlib_clip_bounds; 1.44 +- int xlib_clip_serial; 1.45 +- QPoint redir_offset; 1.46 +-#endif 1.47 +- 1.48 + QPainter *p; 1.49 + 1.50 + /* The pixmap/image constructors will store their objects here */ 1.51 +@@ -145,11 +133,6 @@ struct cairo_qt_surface_t { 1.52 + */ 1.53 + static cairo_bool_t _qpixmaps_have_no_alpha = FALSE; 1.54 + 1.55 +-#if defined(Q_WS_X11) && CAIRO_HAS_XLIB_XRENDER_SURFACE 1.56 +-slim_hidden_proto (cairo_xlib_surface_create); 1.57 +-slim_hidden_proto (cairo_xlib_surface_create_with_xrender_format); 1.58 +-#endif 1.59 +- 1.60 + /** 1.61 + ** Helper methods 1.62 + **/ 1.63 +@@ -498,11 +481,6 @@ _cairo_qt_surface_finish (void *abstract_surface) 1.64 + 1.65 + _cairo_surface_clipper_reset (&qs->clipper); 1.66 + 1.67 +-#if defined(Q_WS_X11) && CAIRO_HAS_XLIB_XRENDER_SURFACE 1.68 +- if (qs->xlib_equiv) 1.69 +- cairo_surface_destroy (qs->xlib_equiv); 1.70 +-#endif 1.71 +- 1.72 + if (qs->image) 1.73 + delete qs->image; 1.74 + 1.75 +@@ -1392,33 +1370,40 @@ _cairo_qt_surface_show_glyphs (void *abstract_surface, 1.76 + cairo_clip_t *clip, 1.77 + int *remaining_glyphs) 1.78 + { 1.79 ++#if (QT_VERSION >= QT_VERSION_CHECK(4, 7, 0)) || defined(QT_GLYPHS_API_BACKPORT) 1.80 + cairo_qt_surface_t *qs = (cairo_qt_surface_t *) abstract_surface; 1.81 + 1.82 +-#if defined(Q_WS_X11) && CAIRO_HAS_XLIB_XRENDER_SURFACE 1.83 +- /* If we have an equivalent X surface, let the xlib surface handle this 1.84 +- * until we figure out how to do this natively with Qt. 1.85 +- */ 1.86 +- if (qs->xlib_equiv) { 1.87 +- D(fprintf(stderr, "q[%p] show_glyphs (x11 equiv) op:%s nglyphs: %d\n", abstract_surface, _opstr(op), num_glyphs)); 1.88 +- 1.89 +- for (int i = 0; i < num_glyphs; i++) { 1.90 +- glyphs[i].x -= qs->redir_offset.x(); 1.91 +- glyphs[i].y -= qs->redir_offset.y(); 1.92 +- } 1.93 +- 1.94 +- return (cairo_int_status_t) 1.95 +- _cairo_surface_show_text_glyphs (qs->xlib_equiv, 1.96 +- op, source, 1.97 +- NULL, 0, 1.98 +- glyphs, num_glyphs, 1.99 +- NULL, 0, 1.100 +- (cairo_text_cluster_flags_t) 0, 1.101 +- scaled_font, 1.102 +- clip); 1.103 ++ // pick out the colour to use from the cairo source 1.104 ++ cairo_solid_pattern_t *solid = (cairo_solid_pattern_t*) source; 1.105 ++ cairo_scaled_glyph_t* glyph; 1.106 ++ // documentation says you have to freeze the cache, but I don't believe it 1.107 ++ _cairo_scaled_font_freeze_cache(scaled_font); 1.108 ++ 1.109 ++ QColor tempColour(solid->color.red * 255, solid->color.green * 255, solid->color.blue * 255); 1.110 ++ QVarLengthArray<QPointF> positions(num_glyphs); 1.111 ++ QVarLengthArray<unsigned int> glyphss(num_glyphs); 1.112 ++ FT_Face face = cairo_ft_scaled_font_lock_face (scaled_font); 1.113 ++ const FT_Size_Metrics& ftMetrics = face->size->metrics; 1.114 ++ QFont font(face->family_name); 1.115 ++ font.setStyleStrategy(QFont::NoFontMerging); 1.116 ++ font.setBold(face->style_flags & FT_STYLE_FLAG_BOLD); 1.117 ++ font.setItalic(face->style_flags & FT_STYLE_FLAG_ITALIC); 1.118 ++ font.setKerning(face->face_flags & FT_FACE_FLAG_KERNING); 1.119 ++ font.setPixelSize(ftMetrics.y_ppem); 1.120 ++ cairo_ft_scaled_font_unlock_face(scaled_font); 1.121 ++ qs->p->setFont(font); 1.122 ++ qs->p->setPen(tempColour); 1.123 ++ for (int currentGlyph = 0; currentGlyph < num_glyphs; currentGlyph++) { 1.124 ++ positions[currentGlyph].setX(glyphs[currentGlyph].x); 1.125 ++ positions[currentGlyph].setY(glyphs[currentGlyph].y); 1.126 ++ glyphss[currentGlyph] = glyphs[currentGlyph].index; 1.127 + } 1.128 +-#endif 1.129 +- 1.130 ++ qt_draw_glyphs(qs->p, glyphss.data(), positions.data(), num_glyphs); 1.131 ++ _cairo_scaled_font_thaw_cache(scaled_font); 1.132 ++ return CAIRO_INT_STATUS_SUCCESS; 1.133 ++#else 1.134 + return CAIRO_INT_STATUS_UNSUPPORTED; 1.135 ++#endif 1.136 + } 1.137 + 1.138 + static cairo_int_status_t 1.139 +@@ -1555,24 +1540,6 @@ _cairo_qt_surface_composite (cairo_operator_t op, 1.140 + } 1.141 + 1.142 + static cairo_status_t 1.143 +-_cairo_qt_surface_flush (void *abstract_surface) 1.144 +-{ 1.145 +- cairo_qt_surface_t *qs = (cairo_qt_surface_t *) abstract_surface; 1.146 +- 1.147 +- if (qs->p == NULL) 1.148 +- return CAIRO_STATUS_SUCCESS; 1.149 +- 1.150 +- if (qs->image || qs->pixmap) { 1.151 +- qs->p->end (); 1.152 +- qs->p->begin (qs->p->device ()); 1.153 +- } else { 1.154 +- qs->p->restore (); 1.155 +- } 1.156 +- 1.157 +- return CAIRO_STATUS_SUCCESS; 1.158 +-} 1.159 +- 1.160 +-static cairo_status_t 1.161 + _cairo_qt_surface_mark_dirty (void *abstract_surface, 1.162 + int x, int y, 1.163 + int width, int height) 1.164 +@@ -1609,7 +1576,7 @@ static const cairo_surface_backend_t cairo_qt_surface_backend = { 1.165 + _cairo_qt_surface_get_extents, 1.166 + NULL, /* old_show_glyphs */ 1.167 + NULL, /* get_font_options */ 1.168 +- _cairo_qt_surface_flush, 1.169 ++ NULL, /* flush */ 1.170 + _cairo_qt_surface_mark_dirty, 1.171 + NULL, /* scaled_font_fini */ 1.172 + NULL, /* scaled_glyph_fini */ 1.173 +@@ -1629,64 +1596,6 @@ static const cairo_surface_backend_t cairo_qt_surface_backend = { 1.174 + NULL, /* show_text_glyphs */ 1.175 + }; 1.176 + 1.177 +-#if defined(Q_WS_X11) && CAIRO_HAS_XLIB_XRENDER_SURFACE 1.178 +-static cairo_surface_t * 1.179 +-_cairo_qt_create_xlib_surface (cairo_qt_surface_t *qs) 1.180 +-{ 1.181 +- if (!qs->p) 1.182 +- return NULL; 1.183 +- 1.184 +- QPaintDevice *pd = qs->p->device(); 1.185 +- if (!pd) 1.186 +- return NULL; 1.187 +- 1.188 +- QPoint offs; 1.189 +- QPaintDevice *rpd = QPainter::redirected(pd, &offs); 1.190 +- if (rpd) { 1.191 +- pd = rpd; 1.192 +- qs->redir_offset = offs; 1.193 +- } 1.194 +- 1.195 +- if (pd->devType() == QInternal::Widget) { 1.196 +- QWidget *w = (QWidget*) pd; 1.197 +- QX11Info xinfo = w->x11Info(); 1.198 +- 1.199 +- return cairo_xlib_surface_create (xinfo.display(), 1.200 +- (Drawable) w->handle (), 1.201 +- (Visual *) xinfo.visual (), 1.202 +- w->width (), w->height ()); 1.203 +- } else if (pd->devType() == QInternal::Pixmap) { 1.204 +- QPixmap *pixmap = (QPixmap*) pd; 1.205 +- QX11Info xinfo = pixmap->x11Info (); 1.206 +- XRenderPictFormat *xrender_format; 1.207 +- int pict_format; 1.208 +- 1.209 +- switch (pixmap->depth ()) { 1.210 +- case 1: 1.211 +- pict_format = PictStandardA1; break; 1.212 +- case 8: 1.213 +- pict_format = PictStandardA8; break; 1.214 +- case 24: 1.215 +- pict_format = PictStandardRGB24; break; 1.216 +- default: 1.217 +- ASSERT_NOT_REACHED; 1.218 +- case 32: 1.219 +- pict_format = PictStandardARGB32; break; 1.220 +- } 1.221 +- xrender_format = XRenderFindStandardFormat (xinfo.display (), 1.222 +- pict_format); 1.223 +- 1.224 +- return cairo_xlib_surface_create_with_xrender_format (xinfo.display(), 1.225 +- (Drawable) pixmap->handle (), 1.226 +- ScreenOfDisplay (xinfo.display (), 1.227 +- xinfo.screen ()), 1.228 +- xrender_format, 1.229 +- pixmap->width (), pixmap->height ()); 1.230 +- } else 1.231 +- return NULL; 1.232 +-} 1.233 +-#endif 1.234 +- 1.235 + cairo_surface_t * 1.236 + cairo_qt_surface_create (QPainter *painter) 1.237 + { 1.238 +@@ -1717,10 +1626,6 @@ cairo_qt_surface_create (QPainter *painter) 1.239 + 1.240 + qs->window = painter->window(); 1.241 + 1.242 +-#if defined(Q_WS_X11) && CAIRO_HAS_XLIB_XRENDER_SURFACE 1.243 +- qs->xlib_equiv = _cairo_qt_create_xlib_surface (qs); 1.244 +-#endif 1.245 +- 1.246 + D(fprintf(stderr, "qpainter_surface_create: window: [%d %d %d %d] pd:%d\n", 1.247 + qs->window.x(), qs->window.y(), qs->window.width(), qs->window.height(), 1.248 + qs->supports_porter_duff)); 1.249 +@@ -1819,10 +1724,6 @@ cairo_qt_surface_create_with_qpixmap (cairo_content_t content, 1.250 + 1.251 + qs->window = QRect(0, 0, width, height); 1.252 + 1.253 +-#if defined(Q_WS_X11) && CAIRO_HAS_XLIB_XRENDER_SURFACE 1.254 +- qs->xlib_equiv = _cairo_qt_create_xlib_surface (qs); 1.255 +-#endif 1.256 +- 1.257 + D(fprintf(stderr, "qpainter_surface_create: qpixmap: [%d %d %d %d] pd:%d\n", 1.258 + qs->window.x(), qs->window.y(), qs->window.width(), qs->window.height(), 1.259 + qs->supports_porter_duff));