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.

michael@0 1 Bug 29092 - Fix glyphs rendering for cairo-qpainter-surface
michael@0 2 diff --git a/src/cairo-qt-surface.cpp b/src/cairo-qt-surface.cpp
michael@0 3 index 2ac06ef..5b61b42 100644
michael@0 4 --- a/src/cairo-qt-surface.cpp
michael@0 5 +++ b/src/cairo-qt-surface.cpp
michael@0 6 @@ -45,6 +45,7 @@
michael@0 7 #include "cairo-surface-clipper-private.h"
michael@0 8 #include "cairo-types-private.h"
michael@0 9
michael@0 10 +#include "cairo-ft.h"
michael@0 11 #include "cairo-qt.h"
michael@0 12
michael@0 13 #include <memory>
michael@0 14 @@ -58,14 +59,10 @@
michael@0 15 #include <QtGui/QPen>
michael@0 16 #include <QtGui/QWidget>
michael@0 17 #include <QtGui/QX11Info>
michael@0 18 +#include <QtCore/QVarLengthArray>
michael@0 19
michael@0 20 -#if CAIRO_HAS_XLIB_XRENDER_SURFACE
michael@0 21 -#include "cairo-xlib.h"
michael@0 22 -#include "cairo-xlib-xrender.h"
michael@0 23 -// I hate X
michael@0 24 -#undef Status
michael@0 25 -#undef CursorShape
michael@0 26 -#undef Bool
michael@0 27 +#if (QT_VERSION >= QT_VERSION_CHECK(4, 7, 0)) || defined(QT_GLYPHS_API_BACKPORT)
michael@0 28 +extern void qt_draw_glyphs(QPainter *, const quint32 *glyphs, const QPointF *positions, int count);
michael@0 29 #endif
michael@0 30
michael@0 31 #include <sys/time.h>
michael@0 32 @@ -118,15 +115,6 @@ struct cairo_qt_surface_t {
michael@0 33
michael@0 34 cairo_bool_t supports_porter_duff;
michael@0 35
michael@0 36 -#if defined(Q_WS_X11) && CAIRO_HAS_XLIB_XRENDER_SURFACE
michael@0 37 - /* temporary, so that we can share the xlib surface's glyphs code */
michael@0 38 - bool xlib_has_clipping;
michael@0 39 - cairo_surface_t *xlib_equiv;
michael@0 40 - QRect xlib_clip_bounds;
michael@0 41 - int xlib_clip_serial;
michael@0 42 - QPoint redir_offset;
michael@0 43 -#endif
michael@0 44 -
michael@0 45 QPainter *p;
michael@0 46
michael@0 47 /* The pixmap/image constructors will store their objects here */
michael@0 48 @@ -145,11 +133,6 @@ struct cairo_qt_surface_t {
michael@0 49 */
michael@0 50 static cairo_bool_t _qpixmaps_have_no_alpha = FALSE;
michael@0 51
michael@0 52 -#if defined(Q_WS_X11) && CAIRO_HAS_XLIB_XRENDER_SURFACE
michael@0 53 -slim_hidden_proto (cairo_xlib_surface_create);
michael@0 54 -slim_hidden_proto (cairo_xlib_surface_create_with_xrender_format);
michael@0 55 -#endif
michael@0 56 -
michael@0 57 /**
michael@0 58 ** Helper methods
michael@0 59 **/
michael@0 60 @@ -498,11 +481,6 @@ _cairo_qt_surface_finish (void *abstract_surface)
michael@0 61
michael@0 62 _cairo_surface_clipper_reset (&qs->clipper);
michael@0 63
michael@0 64 -#if defined(Q_WS_X11) && CAIRO_HAS_XLIB_XRENDER_SURFACE
michael@0 65 - if (qs->xlib_equiv)
michael@0 66 - cairo_surface_destroy (qs->xlib_equiv);
michael@0 67 -#endif
michael@0 68 -
michael@0 69 if (qs->image)
michael@0 70 delete qs->image;
michael@0 71
michael@0 72 @@ -1392,33 +1370,40 @@ _cairo_qt_surface_show_glyphs (void *abstract_surface,
michael@0 73 cairo_clip_t *clip,
michael@0 74 int *remaining_glyphs)
michael@0 75 {
michael@0 76 +#if (QT_VERSION >= QT_VERSION_CHECK(4, 7, 0)) || defined(QT_GLYPHS_API_BACKPORT)
michael@0 77 cairo_qt_surface_t *qs = (cairo_qt_surface_t *) abstract_surface;
michael@0 78
michael@0 79 -#if defined(Q_WS_X11) && CAIRO_HAS_XLIB_XRENDER_SURFACE
michael@0 80 - /* If we have an equivalent X surface, let the xlib surface handle this
michael@0 81 - * until we figure out how to do this natively with Qt.
michael@0 82 - */
michael@0 83 - if (qs->xlib_equiv) {
michael@0 84 - D(fprintf(stderr, "q[%p] show_glyphs (x11 equiv) op:%s nglyphs: %d\n", abstract_surface, _opstr(op), num_glyphs));
michael@0 85 -
michael@0 86 - for (int i = 0; i < num_glyphs; i++) {
michael@0 87 - glyphs[i].x -= qs->redir_offset.x();
michael@0 88 - glyphs[i].y -= qs->redir_offset.y();
michael@0 89 - }
michael@0 90 -
michael@0 91 - return (cairo_int_status_t)
michael@0 92 - _cairo_surface_show_text_glyphs (qs->xlib_equiv,
michael@0 93 - op, source,
michael@0 94 - NULL, 0,
michael@0 95 - glyphs, num_glyphs,
michael@0 96 - NULL, 0,
michael@0 97 - (cairo_text_cluster_flags_t) 0,
michael@0 98 - scaled_font,
michael@0 99 - clip);
michael@0 100 + // pick out the colour to use from the cairo source
michael@0 101 + cairo_solid_pattern_t *solid = (cairo_solid_pattern_t*) source;
michael@0 102 + cairo_scaled_glyph_t* glyph;
michael@0 103 + // documentation says you have to freeze the cache, but I don't believe it
michael@0 104 + _cairo_scaled_font_freeze_cache(scaled_font);
michael@0 105 +
michael@0 106 + QColor tempColour(solid->color.red * 255, solid->color.green * 255, solid->color.blue * 255);
michael@0 107 + QVarLengthArray<QPointF> positions(num_glyphs);
michael@0 108 + QVarLengthArray<unsigned int> glyphss(num_glyphs);
michael@0 109 + FT_Face face = cairo_ft_scaled_font_lock_face (scaled_font);
michael@0 110 + const FT_Size_Metrics& ftMetrics = face->size->metrics;
michael@0 111 + QFont font(face->family_name);
michael@0 112 + font.setStyleStrategy(QFont::NoFontMerging);
michael@0 113 + font.setBold(face->style_flags & FT_STYLE_FLAG_BOLD);
michael@0 114 + font.setItalic(face->style_flags & FT_STYLE_FLAG_ITALIC);
michael@0 115 + font.setKerning(face->face_flags & FT_FACE_FLAG_KERNING);
michael@0 116 + font.setPixelSize(ftMetrics.y_ppem);
michael@0 117 + cairo_ft_scaled_font_unlock_face(scaled_font);
michael@0 118 + qs->p->setFont(font);
michael@0 119 + qs->p->setPen(tempColour);
michael@0 120 + for (int currentGlyph = 0; currentGlyph < num_glyphs; currentGlyph++) {
michael@0 121 + positions[currentGlyph].setX(glyphs[currentGlyph].x);
michael@0 122 + positions[currentGlyph].setY(glyphs[currentGlyph].y);
michael@0 123 + glyphss[currentGlyph] = glyphs[currentGlyph].index;
michael@0 124 }
michael@0 125 -#endif
michael@0 126 -
michael@0 127 + qt_draw_glyphs(qs->p, glyphss.data(), positions.data(), num_glyphs);
michael@0 128 + _cairo_scaled_font_thaw_cache(scaled_font);
michael@0 129 + return CAIRO_INT_STATUS_SUCCESS;
michael@0 130 +#else
michael@0 131 return CAIRO_INT_STATUS_UNSUPPORTED;
michael@0 132 +#endif
michael@0 133 }
michael@0 134
michael@0 135 static cairo_int_status_t
michael@0 136 @@ -1555,24 +1540,6 @@ _cairo_qt_surface_composite (cairo_operator_t op,
michael@0 137 }
michael@0 138
michael@0 139 static cairo_status_t
michael@0 140 -_cairo_qt_surface_flush (void *abstract_surface)
michael@0 141 -{
michael@0 142 - cairo_qt_surface_t *qs = (cairo_qt_surface_t *) abstract_surface;
michael@0 143 -
michael@0 144 - if (qs->p == NULL)
michael@0 145 - return CAIRO_STATUS_SUCCESS;
michael@0 146 -
michael@0 147 - if (qs->image || qs->pixmap) {
michael@0 148 - qs->p->end ();
michael@0 149 - qs->p->begin (qs->p->device ());
michael@0 150 - } else {
michael@0 151 - qs->p->restore ();
michael@0 152 - }
michael@0 153 -
michael@0 154 - return CAIRO_STATUS_SUCCESS;
michael@0 155 -}
michael@0 156 -
michael@0 157 -static cairo_status_t
michael@0 158 _cairo_qt_surface_mark_dirty (void *abstract_surface,
michael@0 159 int x, int y,
michael@0 160 int width, int height)
michael@0 161 @@ -1609,7 +1576,7 @@ static const cairo_surface_backend_t cairo_qt_surface_backend = {
michael@0 162 _cairo_qt_surface_get_extents,
michael@0 163 NULL, /* old_show_glyphs */
michael@0 164 NULL, /* get_font_options */
michael@0 165 - _cairo_qt_surface_flush,
michael@0 166 + NULL, /* flush */
michael@0 167 _cairo_qt_surface_mark_dirty,
michael@0 168 NULL, /* scaled_font_fini */
michael@0 169 NULL, /* scaled_glyph_fini */
michael@0 170 @@ -1629,64 +1596,6 @@ static const cairo_surface_backend_t cairo_qt_surface_backend = {
michael@0 171 NULL, /* show_text_glyphs */
michael@0 172 };
michael@0 173
michael@0 174 -#if defined(Q_WS_X11) && CAIRO_HAS_XLIB_XRENDER_SURFACE
michael@0 175 -static cairo_surface_t *
michael@0 176 -_cairo_qt_create_xlib_surface (cairo_qt_surface_t *qs)
michael@0 177 -{
michael@0 178 - if (!qs->p)
michael@0 179 - return NULL;
michael@0 180 -
michael@0 181 - QPaintDevice *pd = qs->p->device();
michael@0 182 - if (!pd)
michael@0 183 - return NULL;
michael@0 184 -
michael@0 185 - QPoint offs;
michael@0 186 - QPaintDevice *rpd = QPainter::redirected(pd, &offs);
michael@0 187 - if (rpd) {
michael@0 188 - pd = rpd;
michael@0 189 - qs->redir_offset = offs;
michael@0 190 - }
michael@0 191 -
michael@0 192 - if (pd->devType() == QInternal::Widget) {
michael@0 193 - QWidget *w = (QWidget*) pd;
michael@0 194 - QX11Info xinfo = w->x11Info();
michael@0 195 -
michael@0 196 - return cairo_xlib_surface_create (xinfo.display(),
michael@0 197 - (Drawable) w->handle (),
michael@0 198 - (Visual *) xinfo.visual (),
michael@0 199 - w->width (), w->height ());
michael@0 200 - } else if (pd->devType() == QInternal::Pixmap) {
michael@0 201 - QPixmap *pixmap = (QPixmap*) pd;
michael@0 202 - QX11Info xinfo = pixmap->x11Info ();
michael@0 203 - XRenderPictFormat *xrender_format;
michael@0 204 - int pict_format;
michael@0 205 -
michael@0 206 - switch (pixmap->depth ()) {
michael@0 207 - case 1:
michael@0 208 - pict_format = PictStandardA1; break;
michael@0 209 - case 8:
michael@0 210 - pict_format = PictStandardA8; break;
michael@0 211 - case 24:
michael@0 212 - pict_format = PictStandardRGB24; break;
michael@0 213 - default:
michael@0 214 - ASSERT_NOT_REACHED;
michael@0 215 - case 32:
michael@0 216 - pict_format = PictStandardARGB32; break;
michael@0 217 - }
michael@0 218 - xrender_format = XRenderFindStandardFormat (xinfo.display (),
michael@0 219 - pict_format);
michael@0 220 -
michael@0 221 - return cairo_xlib_surface_create_with_xrender_format (xinfo.display(),
michael@0 222 - (Drawable) pixmap->handle (),
michael@0 223 - ScreenOfDisplay (xinfo.display (),
michael@0 224 - xinfo.screen ()),
michael@0 225 - xrender_format,
michael@0 226 - pixmap->width (), pixmap->height ());
michael@0 227 - } else
michael@0 228 - return NULL;
michael@0 229 -}
michael@0 230 -#endif
michael@0 231 -
michael@0 232 cairo_surface_t *
michael@0 233 cairo_qt_surface_create (QPainter *painter)
michael@0 234 {
michael@0 235 @@ -1717,10 +1626,6 @@ cairo_qt_surface_create (QPainter *painter)
michael@0 236
michael@0 237 qs->window = painter->window();
michael@0 238
michael@0 239 -#if defined(Q_WS_X11) && CAIRO_HAS_XLIB_XRENDER_SURFACE
michael@0 240 - qs->xlib_equiv = _cairo_qt_create_xlib_surface (qs);
michael@0 241 -#endif
michael@0 242 -
michael@0 243 D(fprintf(stderr, "qpainter_surface_create: window: [%d %d %d %d] pd:%d\n",
michael@0 244 qs->window.x(), qs->window.y(), qs->window.width(), qs->window.height(),
michael@0 245 qs->supports_porter_duff));
michael@0 246 @@ -1819,10 +1724,6 @@ cairo_qt_surface_create_with_qpixmap (cairo_content_t content,
michael@0 247
michael@0 248 qs->window = QRect(0, 0, width, height);
michael@0 249
michael@0 250 -#if defined(Q_WS_X11) && CAIRO_HAS_XLIB_XRENDER_SURFACE
michael@0 251 - qs->xlib_equiv = _cairo_qt_create_xlib_surface (qs);
michael@0 252 -#endif
michael@0 253 -
michael@0 254 D(fprintf(stderr, "qpainter_surface_create: qpixmap: [%d %d %d %d] pd:%d\n",
michael@0 255 qs->window.x(), qs->window.y(), qs->window.width(), qs->window.height(),
michael@0 256 qs->supports_porter_duff));

mercurial