gfx/cairo/cairo_qt_glyphs.patch

Tue, 06 Jan 2015 21:39:09 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Tue, 06 Jan 2015 21:39:09 +0100
branch
TOR_BUG_9701
changeset 8
97036ab72558
permissions
-rw-r--r--

Conditionally force memory storage according to privacy.thirdparty.isolate;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.

     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
     6 @@ -45,6 +45,7 @@
     7  #include "cairo-surface-clipper-private.h"
     8  #include "cairo-types-private.h"
    10 +#include "cairo-ft.h"
    11  #include "cairo-qt.h"
    13  #include <memory>
    14 @@ -58,14 +59,10 @@
    15  #include <QtGui/QPen>
    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"
    23 -// I hate X
    24 -#undef Status
    25 -#undef CursorShape
    26 -#undef Bool
    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);
    29  #endif
    31  #include <sys/time.h>
    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;
    43 -#endif
    44 -
    45      QPainter *p;
    47      /* The pixmap/image constructors will store their objects here */
    48 @@ -145,11 +133,6 @@ struct cairo_qt_surface_t {
    49   */
    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);
    55 -#endif
    56 -
    57  /**
    58   ** Helper methods
    59   **/
    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
    65 -    if (qs->xlib_equiv)
    66 -        cairo_surface_destroy (qs->xlib_equiv);
    67 -#endif
    68 -
    69      if (qs->image)
    70          delete qs->image;
    72 @@ -1392,33 +1370,40 @@ _cairo_qt_surface_show_glyphs (void *abstract_surface,
    73  			       cairo_clip_t *clip,
    74  			       int *remaining_glyphs)
    75  {
    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.
    82 -     */
    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));
    85 -
    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();
    89 -	}
    90 -
    91 -        return (cairo_int_status_t)
    92 -               _cairo_surface_show_text_glyphs (qs->xlib_equiv,
    93 -						op, source,
    94 -						NULL, 0,
    95 -						glyphs, num_glyphs,
    96 -						NULL, 0,
    97 -						(cairo_text_cluster_flags_t) 0,
    98 -						scaled_font,
    99 -						clip);
   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);
   105 +
   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;
   124      }
   125 -#endif
   126 -
   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;
   130 +#else
   131      return CAIRO_INT_STATUS_UNSUPPORTED;
   132 +#endif
   133  }
   135  static cairo_int_status_t
   136 @@ -1555,24 +1540,6 @@ _cairo_qt_surface_composite (cairo_operator_t op,
   137  }
   139  static cairo_status_t
   140 -_cairo_qt_surface_flush (void *abstract_surface)
   141 -{
   142 -    cairo_qt_surface_t *qs = (cairo_qt_surface_t *) abstract_surface;
   143 -
   144 -    if (qs->p == NULL)
   145 -	return CAIRO_STATUS_SUCCESS;
   146 -
   147 -    if (qs->image || qs->pixmap) {
   148 -	qs->p->end ();
   149 -	qs->p->begin (qs->p->device ());
   150 -    } else {
   151 -	qs->p->restore ();
   152 -    }
   153 -
   154 -    return CAIRO_STATUS_SUCCESS;
   155 -}
   156 -
   157 -static cairo_status_t
   158  _cairo_qt_surface_mark_dirty (void *abstract_surface,
   159  			      int x, int y,
   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,
   166 +    NULL, /* 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 */
   172  };
   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)
   177 -{
   178 -    if (!qs->p)
   179 -	return NULL;
   180 -
   181 -    QPaintDevice *pd = qs->p->device();
   182 -    if (!pd)
   183 -	return NULL;
   184 -
   185 -    QPoint offs;
   186 -    QPaintDevice *rpd = QPainter::redirected(pd, &offs);
   187 -    if (rpd) {
   188 -	pd = rpd;
   189 -	qs->redir_offset = offs;
   190 -    }
   191 -
   192 -    if (pd->devType() == QInternal::Widget) {
   193 -	QWidget *w = (QWidget*) pd;
   194 -	QX11Info xinfo = w->x11Info();
   195 -
   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;
   204 -	int pict_format;
   205 -
   206 -	switch (pixmap->depth ()) {
   207 -	case 1:
   208 -	    pict_format = PictStandardA1; break;
   209 -	case 8:
   210 -	    pict_format = PictStandardA8; break;
   211 -	case 24:
   212 -	    pict_format = PictStandardRGB24; break;
   213 -	default:
   214 -	    ASSERT_NOT_REACHED;
   215 -	case 32:
   216 -	    pict_format = PictStandardARGB32; break;
   217 -	}
   218 -	xrender_format = XRenderFindStandardFormat (xinfo.display (),
   219 -		                                    pict_format);
   220 -
   221 -	return cairo_xlib_surface_create_with_xrender_format (xinfo.display(),
   222 -					  (Drawable) pixmap->handle (),
   223 -					  ScreenOfDisplay (xinfo.display (),
   224 -							   xinfo.screen ()),
   225 -					  xrender_format,
   226 -					  pixmap->width (), pixmap->height ());
   227 -    } else
   228 -	return NULL;
   229 -}
   230 -#endif
   231 -
   232  cairo_surface_t *
   233  cairo_qt_surface_create (QPainter *painter)
   234  {
   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);
   241 -#endif
   242 -
   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);
   252 -#endif
   253 -
   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));

mercurial