gfx/cairo/cairo_qt_glyphs.patch

changeset 0
6474c204b198
     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));

mercurial