diff options
Diffstat (limited to 'gfx/cairo/cairo_qt_glyphs.patch')
-rw-r--r-- | gfx/cairo/cairo_qt_glyphs.patch | 256 |
1 files changed, 256 insertions, 0 deletions
diff --git a/gfx/cairo/cairo_qt_glyphs.patch b/gfx/cairo/cairo_qt_glyphs.patch new file mode 100644 index 000000000..b12356287 --- /dev/null +++ b/gfx/cairo/cairo_qt_glyphs.patch @@ -0,0 +1,256 @@ +Bug 29092 - Fix glyphs rendering for cairo-qpainter-surface +diff --git a/src/cairo-qt-surface.cpp b/src/cairo-qt-surface.cpp +index 2ac06ef..5b61b42 100644 +--- a/src/cairo-qt-surface.cpp ++++ b/src/cairo-qt-surface.cpp +@@ -45,6 +45,7 @@ + #include "cairo-surface-clipper-private.h" + #include "cairo-types-private.h" + ++#include "cairo-ft.h" + #include "cairo-qt.h" + + #include <memory> +@@ -58,14 +59,10 @@ + #include <QtGui/QPen> + #include <QtGui/QWidget> + #include <QtGui/QX11Info> ++#include <QtCore/QVarLengthArray> + +-#if CAIRO_HAS_XLIB_XRENDER_SURFACE +-#include "cairo-xlib.h" +-#include "cairo-xlib-xrender.h" +-// I hate X +-#undef Status +-#undef CursorShape +-#undef Bool ++#if (QT_VERSION >= QT_VERSION_CHECK(4, 7, 0)) || defined(QT_GLYPHS_API_BACKPORT) ++extern void qt_draw_glyphs(QPainter *, const quint32 *glyphs, const QPointF *positions, int count); + #endif + + #include <sys/time.h> +@@ -118,15 +115,6 @@ struct cairo_qt_surface_t { + + cairo_bool_t supports_porter_duff; + +-#if defined(Q_WS_X11) && CAIRO_HAS_XLIB_XRENDER_SURFACE +- /* temporary, so that we can share the xlib surface's glyphs code */ +- bool xlib_has_clipping; +- cairo_surface_t *xlib_equiv; +- QRect xlib_clip_bounds; +- int xlib_clip_serial; +- QPoint redir_offset; +-#endif +- + QPainter *p; + + /* The pixmap/image constructors will store their objects here */ +@@ -145,11 +133,6 @@ struct cairo_qt_surface_t { + */ + static cairo_bool_t _qpixmaps_have_no_alpha = FALSE; + +-#if defined(Q_WS_X11) && CAIRO_HAS_XLIB_XRENDER_SURFACE +-slim_hidden_proto (cairo_xlib_surface_create); +-slim_hidden_proto (cairo_xlib_surface_create_with_xrender_format); +-#endif +- + /** + ** Helper methods + **/ +@@ -498,11 +481,6 @@ _cairo_qt_surface_finish (void *abstract_surface) + + _cairo_surface_clipper_reset (&qs->clipper); + +-#if defined(Q_WS_X11) && CAIRO_HAS_XLIB_XRENDER_SURFACE +- if (qs->xlib_equiv) +- cairo_surface_destroy (qs->xlib_equiv); +-#endif +- + if (qs->image) + delete qs->image; + +@@ -1392,33 +1370,40 @@ _cairo_qt_surface_show_glyphs (void *abstract_surface, + cairo_clip_t *clip, + int *remaining_glyphs) + { ++#if (QT_VERSION >= QT_VERSION_CHECK(4, 7, 0)) || defined(QT_GLYPHS_API_BACKPORT) + cairo_qt_surface_t *qs = (cairo_qt_surface_t *) abstract_surface; + +-#if defined(Q_WS_X11) && CAIRO_HAS_XLIB_XRENDER_SURFACE +- /* If we have an equivalent X surface, let the xlib surface handle this +- * until we figure out how to do this natively with Qt. +- */ +- if (qs->xlib_equiv) { +- D(fprintf(stderr, "q[%p] show_glyphs (x11 equiv) op:%s nglyphs: %d\n", abstract_surface, _opstr(op), num_glyphs)); +- +- for (int i = 0; i < num_glyphs; i++) { +- glyphs[i].x -= qs->redir_offset.x(); +- glyphs[i].y -= qs->redir_offset.y(); +- } +- +- return (cairo_int_status_t) +- _cairo_surface_show_text_glyphs (qs->xlib_equiv, +- op, source, +- NULL, 0, +- glyphs, num_glyphs, +- NULL, 0, +- (cairo_text_cluster_flags_t) 0, +- scaled_font, +- clip); ++ // pick out the colour to use from the cairo source ++ cairo_solid_pattern_t *solid = (cairo_solid_pattern_t*) source; ++ cairo_scaled_glyph_t* glyph; ++ // documentation says you have to freeze the cache, but I don't believe it ++ _cairo_scaled_font_freeze_cache(scaled_font); ++ ++ QColor tempColour(solid->color.red * 255, solid->color.green * 255, solid->color.blue * 255); ++ QVarLengthArray<QPointF> positions(num_glyphs); ++ QVarLengthArray<unsigned int> glyphss(num_glyphs); ++ FT_Face face = cairo_ft_scaled_font_lock_face (scaled_font); ++ const FT_Size_Metrics& ftMetrics = face->size->metrics; ++ QFont font(face->family_name); ++ font.setStyleStrategy(QFont::NoFontMerging); ++ font.setBold(face->style_flags & FT_STYLE_FLAG_BOLD); ++ font.setItalic(face->style_flags & FT_STYLE_FLAG_ITALIC); ++ font.setKerning(face->face_flags & FT_FACE_FLAG_KERNING); ++ font.setPixelSize(ftMetrics.y_ppem); ++ cairo_ft_scaled_font_unlock_face(scaled_font); ++ qs->p->setFont(font); ++ qs->p->setPen(tempColour); ++ for (int currentGlyph = 0; currentGlyph < num_glyphs; currentGlyph++) { ++ positions[currentGlyph].setX(glyphs[currentGlyph].x); ++ positions[currentGlyph].setY(glyphs[currentGlyph].y); ++ glyphss[currentGlyph] = glyphs[currentGlyph].index; + } +-#endif +- ++ qt_draw_glyphs(qs->p, glyphss.data(), positions.data(), num_glyphs); ++ _cairo_scaled_font_thaw_cache(scaled_font); ++ return CAIRO_INT_STATUS_SUCCESS; ++#else + return CAIRO_INT_STATUS_UNSUPPORTED; ++#endif + } + + static cairo_int_status_t +@@ -1555,24 +1540,6 @@ _cairo_qt_surface_composite (cairo_operator_t op, + } + + static cairo_status_t +-_cairo_qt_surface_flush (void *abstract_surface) +-{ +- cairo_qt_surface_t *qs = (cairo_qt_surface_t *) abstract_surface; +- +- if (qs->p == NULL) +- return CAIRO_STATUS_SUCCESS; +- +- if (qs->image || qs->pixmap) { +- qs->p->end (); +- qs->p->begin (qs->p->device ()); +- } else { +- qs->p->restore (); +- } +- +- return CAIRO_STATUS_SUCCESS; +-} +- +-static cairo_status_t + _cairo_qt_surface_mark_dirty (void *abstract_surface, + int x, int y, + int width, int height) +@@ -1609,7 +1576,7 @@ static const cairo_surface_backend_t cairo_qt_surface_backend = { + _cairo_qt_surface_get_extents, + NULL, /* old_show_glyphs */ + NULL, /* get_font_options */ +- _cairo_qt_surface_flush, ++ NULL, /* flush */ + _cairo_qt_surface_mark_dirty, + NULL, /* scaled_font_fini */ + NULL, /* scaled_glyph_fini */ +@@ -1629,64 +1596,6 @@ static const cairo_surface_backend_t cairo_qt_surface_backend = { + NULL, /* show_text_glyphs */ + }; + +-#if defined(Q_WS_X11) && CAIRO_HAS_XLIB_XRENDER_SURFACE +-static cairo_surface_t * +-_cairo_qt_create_xlib_surface (cairo_qt_surface_t *qs) +-{ +- if (!qs->p) +- return NULL; +- +- QPaintDevice *pd = qs->p->device(); +- if (!pd) +- return NULL; +- +- QPoint offs; +- QPaintDevice *rpd = QPainter::redirected(pd, &offs); +- if (rpd) { +- pd = rpd; +- qs->redir_offset = offs; +- } +- +- if (pd->devType() == QInternal::Widget) { +- QWidget *w = (QWidget*) pd; +- QX11Info xinfo = w->x11Info(); +- +- return cairo_xlib_surface_create (xinfo.display(), +- (Drawable) w->handle (), +- (Visual *) xinfo.visual (), +- w->width (), w->height ()); +- } else if (pd->devType() == QInternal::Pixmap) { +- QPixmap *pixmap = (QPixmap*) pd; +- QX11Info xinfo = pixmap->x11Info (); +- XRenderPictFormat *xrender_format; +- int pict_format; +- +- switch (pixmap->depth ()) { +- case 1: +- pict_format = PictStandardA1; break; +- case 8: +- pict_format = PictStandardA8; break; +- case 24: +- pict_format = PictStandardRGB24; break; +- default: +- ASSERT_NOT_REACHED; +- case 32: +- pict_format = PictStandardARGB32; break; +- } +- xrender_format = XRenderFindStandardFormat (xinfo.display (), +- pict_format); +- +- return cairo_xlib_surface_create_with_xrender_format (xinfo.display(), +- (Drawable) pixmap->handle (), +- ScreenOfDisplay (xinfo.display (), +- xinfo.screen ()), +- xrender_format, +- pixmap->width (), pixmap->height ()); +- } else +- return NULL; +-} +-#endif +- + cairo_surface_t * + cairo_qt_surface_create (QPainter *painter) + { +@@ -1717,10 +1626,6 @@ cairo_qt_surface_create (QPainter *painter) + + qs->window = painter->window(); + +-#if defined(Q_WS_X11) && CAIRO_HAS_XLIB_XRENDER_SURFACE +- qs->xlib_equiv = _cairo_qt_create_xlib_surface (qs); +-#endif +- + D(fprintf(stderr, "qpainter_surface_create: window: [%d %d %d %d] pd:%d\n", + qs->window.x(), qs->window.y(), qs->window.width(), qs->window.height(), + qs->supports_porter_duff)); +@@ -1819,10 +1724,6 @@ cairo_qt_surface_create_with_qpixmap (cairo_content_t content, + + qs->window = QRect(0, 0, width, height); + +-#if defined(Q_WS_X11) && CAIRO_HAS_XLIB_XRENDER_SURFACE +- qs->xlib_equiv = _cairo_qt_create_xlib_surface (qs); +-#endif +- + D(fprintf(stderr, "qpainter_surface_create: qpixmap: [%d %d %d %d] pd:%d\n", + qs->window.x(), qs->window.y(), qs->window.width(), qs->window.height(), + qs->supports_porter_duff)); |