texlive[48952] Build/source/libs: cairo 1.16.0

commits+kakuto at tug.org commits+kakuto at tug.org
Sat Oct 20 05:19:36 CEST 2018


Revision: 48952
          http://tug.org/svn/texlive?view=revision&revision=48952
Author:   kakuto
Date:     2018-10-20 05:19:36 +0200 (Sat, 20 Oct 2018)
Log Message:
-----------
cairo 1.16.0

Modified Paths:
--------------
    trunk/Build/source/libs/README
    trunk/Build/source/libs/cairo/ChangeLog
    trunk/Build/source/libs/cairo/Makefile.am
    trunk/Build/source/libs/cairo/Makefile.in
    trunk/Build/source/libs/cairo/README
    trunk/Build/source/libs/cairo/TLpatches/ChangeLog
    trunk/Build/source/libs/cairo/TLpatches/TL-Changes
    trunk/Build/source/libs/cairo/cairo-src/BUGS
    trunk/Build/source/libs/cairo/cairo-src/HACKING
    trunk/Build/source/libs/cairo/cairo-src/INSTALL
    trunk/Build/source/libs/cairo/cairo-src/NEWS
    trunk/Build/source/libs/cairo/cairo-src/README
    trunk/Build/source/libs/cairo/cairo-src/RELEASING
    trunk/Build/source/libs/cairo/cairo-src/build/Makefile.am.gtk-doc
    trunk/Build/source/libs/cairo/cairo-src/build/Makefile.am.releasing
    trunk/Build/source/libs/cairo/cairo-src/build/Makefile.win32.features
    trunk/Build/source/libs/cairo/cairo-src/build/Makefile.win32.features-h
    trunk/Build/source/libs/cairo/cairo-src/build/aclocal.cairo.m4
    trunk/Build/source/libs/cairo/cairo-src/build/aclocal.float.m4
    trunk/Build/source/libs/cairo/cairo-src/build/aclocal.pkg.m4
    trunk/Build/source/libs/cairo/cairo-src/build/configure.ac.features
    trunk/Build/source/libs/cairo/cairo-src/build/configure.ac.system
    trunk/Build/source/libs/cairo/cairo-src/build/configure.ac.tools
    trunk/Build/source/libs/cairo/cairo-src/build/gtk-doc.m4
    trunk/Build/source/libs/cairo/cairo-src/cairo-version.h
    trunk/Build/source/libs/cairo/cairo-src/config.h.in
    trunk/Build/source/libs/cairo/cairo-src/configure.ac
    trunk/Build/source/libs/cairo/cairo-src/src/Makefile.am.features
    trunk/Build/source/libs/cairo/cairo-src/src/Makefile.sources
    trunk/Build/source/libs/cairo/cairo-src/src/Makefile.win32.features
    trunk/Build/source/libs/cairo/cairo-src/src/cairo-analysis-surface.c
    trunk/Build/source/libs/cairo/cairo-src/src/cairo-atomic-private.h
    trunk/Build/source/libs/cairo/cairo-src/src/cairo-atomic.c
    trunk/Build/source/libs/cairo/cairo-src/src/cairo-backend-private.h
    trunk/Build/source/libs/cairo/cairo-src/src/cairo-base64-stream.c
    trunk/Build/source/libs/cairo/cairo-src/src/cairo-base85-stream.c
    trunk/Build/source/libs/cairo/cairo-src/src/cairo-bentley-ottmann-rectangular.c
    trunk/Build/source/libs/cairo/cairo-src/src/cairo-bentley-ottmann.c
    trunk/Build/source/libs/cairo/cairo-src/src/cairo-botor-scan-converter.c
    trunk/Build/source/libs/cairo/cairo-src/src/cairo-box-inline.h
    trunk/Build/source/libs/cairo/cairo-src/src/cairo-boxes-private.h
    trunk/Build/source/libs/cairo/cairo-src/src/cairo-boxes.c
    trunk/Build/source/libs/cairo/cairo-src/src/cairo-cff-subset.c
    trunk/Build/source/libs/cairo/cairo-src/src/cairo-clip-boxes.c
    trunk/Build/source/libs/cairo/cairo-src/src/cairo-clip-tor-scan-converter.c
    trunk/Build/source/libs/cairo/cairo-src/src/cairo-clip.c
    trunk/Build/source/libs/cairo/cairo-src/src/cairo-cogl-context.c
    trunk/Build/source/libs/cairo/cairo-src/src/cairo-cogl-gradient.c
    trunk/Build/source/libs/cairo/cairo-src/src/cairo-cogl-surface.c
    trunk/Build/source/libs/cairo/cairo-src/src/cairo-compiler-private.h
    trunk/Build/source/libs/cairo/cairo-src/src/cairo-composite-rectangles.c
    trunk/Build/source/libs/cairo/cairo-src/src/cairo-damage.c
    trunk/Build/source/libs/cairo/cairo-src/src/cairo-debug.c
    trunk/Build/source/libs/cairo/cairo-src/src/cairo-default-context.c
    trunk/Build/source/libs/cairo/cairo-src/src/cairo-deflate-stream.c
    trunk/Build/source/libs/cairo/cairo-src/src/cairo-device.c
    trunk/Build/source/libs/cairo/cairo-src/src/cairo-directfb-surface.c
    trunk/Build/source/libs/cairo/cairo-src/src/cairo-error-private.h
    trunk/Build/source/libs/cairo/cairo-src/src/cairo-font-face-twin.c
    trunk/Build/source/libs/cairo/cairo-src/src/cairo-font-face.c
    trunk/Build/source/libs/cairo/cairo-src/src/cairo-font-options.c
    trunk/Build/source/libs/cairo/cairo-src/src/cairo-freed-pool-private.h
    trunk/Build/source/libs/cairo/cairo-src/src/cairo-freed-pool.c
    trunk/Build/source/libs/cairo/cairo-src/src/cairo-freelist-private.h
    trunk/Build/source/libs/cairo/cairo-src/src/cairo-freelist.c
    trunk/Build/source/libs/cairo/cairo-src/src/cairo-ft-font.c
    trunk/Build/source/libs/cairo/cairo-src/src/cairo-gl-composite.c
    trunk/Build/source/libs/cairo/cairo-src/src/cairo-gl-device.c
    trunk/Build/source/libs/cairo/cairo-src/src/cairo-gl-dispatch.c
    trunk/Build/source/libs/cairo/cairo-src/src/cairo-gl-glyphs.c
    trunk/Build/source/libs/cairo/cairo-src/src/cairo-gl-gradient-private.h
    trunk/Build/source/libs/cairo/cairo-src/src/cairo-gl-gradient.c
    trunk/Build/source/libs/cairo/cairo-src/src/cairo-gl-info.c
    trunk/Build/source/libs/cairo/cairo-src/src/cairo-gl-msaa-compositor.c
    trunk/Build/source/libs/cairo/cairo-src/src/cairo-gl-operand.c
    trunk/Build/source/libs/cairo/cairo-src/src/cairo-gl-private.h
    trunk/Build/source/libs/cairo/cairo-src/src/cairo-gl-shaders.c
    trunk/Build/source/libs/cairo/cairo-src/src/cairo-gl-source.c
    trunk/Build/source/libs/cairo/cairo-src/src/cairo-gl-spans-compositor.c
    trunk/Build/source/libs/cairo/cairo-src/src/cairo-gl-surface.c
    trunk/Build/source/libs/cairo/cairo-src/src/cairo-gl-traps-compositor.c
    trunk/Build/source/libs/cairo/cairo-src/src/cairo-gl.h
    trunk/Build/source/libs/cairo/cairo-src/src/cairo-glx-context.c
    trunk/Build/source/libs/cairo/cairo-src/src/cairo-gstate-private.h
    trunk/Build/source/libs/cairo/cairo-src/src/cairo-gstate.c
    trunk/Build/source/libs/cairo/cairo-src/src/cairo-hash.c
    trunk/Build/source/libs/cairo/cairo-src/src/cairo-image-compositor.c
    trunk/Build/source/libs/cairo/cairo-src/src/cairo-image-source.c
    trunk/Build/source/libs/cairo/cairo-src/src/cairo-image-surface-private.h
    trunk/Build/source/libs/cairo/cairo-src/src/cairo-image-surface.c
    trunk/Build/source/libs/cairo/cairo-src/src/cairo-line.c
    trunk/Build/source/libs/cairo/cairo-src/src/cairo-lzw.c
    trunk/Build/source/libs/cairo/cairo-src/src/cairo-malloc-private.h
    trunk/Build/source/libs/cairo/cairo-src/src/cairo-matrix.c
    trunk/Build/source/libs/cairo/cairo-src/src/cairo-mempool.c
    trunk/Build/source/libs/cairo/cairo-src/src/cairo-mesh-pattern-rasterizer.c
    trunk/Build/source/libs/cairo/cairo-src/src/cairo-misc.c
    trunk/Build/source/libs/cairo/cairo-src/src/cairo-mono-scan-converter.c
    trunk/Build/source/libs/cairo/cairo-src/src/cairo-os2-surface.c
    trunk/Build/source/libs/cairo/cairo-src/src/cairo-output-stream.c
    trunk/Build/source/libs/cairo/cairo-src/src/cairo-paginated-private.h
    trunk/Build/source/libs/cairo/cairo-src/src/cairo-paginated-surface.c
    trunk/Build/source/libs/cairo/cairo-src/src/cairo-path-bounds.c
    trunk/Build/source/libs/cairo/cairo-src/src/cairo-path-fixed.c
    trunk/Build/source/libs/cairo/cairo-src/src/cairo-path.c
    trunk/Build/source/libs/cairo/cairo-src/src/cairo-pattern-private.h
    trunk/Build/source/libs/cairo/cairo-src/src/cairo-pattern.c
    trunk/Build/source/libs/cairo/cairo-src/src/cairo-pdf-operators-private.h
    trunk/Build/source/libs/cairo/cairo-src/src/cairo-pdf-operators.c
    trunk/Build/source/libs/cairo/cairo-src/src/cairo-pdf-shading.c
    trunk/Build/source/libs/cairo/cairo-src/src/cairo-pdf-surface-private.h
    trunk/Build/source/libs/cairo/cairo-src/src/cairo-pdf-surface.c
    trunk/Build/source/libs/cairo/cairo-src/src/cairo-pdf.h
    trunk/Build/source/libs/cairo/cairo-src/src/cairo-pen.c
    trunk/Build/source/libs/cairo/cairo-src/src/cairo-png.c
    trunk/Build/source/libs/cairo/cairo-src/src/cairo-polygon-intersect.c
    trunk/Build/source/libs/cairo/cairo-src/src/cairo-polygon-reduce.c
    trunk/Build/source/libs/cairo/cairo-src/src/cairo-polygon.c
    trunk/Build/source/libs/cairo/cairo-src/src/cairo-ps-surface-private.h
    trunk/Build/source/libs/cairo/cairo-src/src/cairo-ps-surface.c
    trunk/Build/source/libs/cairo/cairo-src/src/cairo-qt-surface.cpp
    trunk/Build/source/libs/cairo/cairo-src/src/cairo-quartz-font.c
    trunk/Build/source/libs/cairo/cairo-src/src/cairo-quartz-image-surface.c
    trunk/Build/source/libs/cairo/cairo-src/src/cairo-quartz-image.h
    trunk/Build/source/libs/cairo/cairo-src/src/cairo-quartz-private.h
    trunk/Build/source/libs/cairo/cairo-src/src/cairo-quartz-surface.c
    trunk/Build/source/libs/cairo/cairo-src/src/cairo-quartz.h
    trunk/Build/source/libs/cairo/cairo-src/src/cairo-recording-surface-private.h
    trunk/Build/source/libs/cairo/cairo-src/src/cairo-recording-surface.c
    trunk/Build/source/libs/cairo/cairo-src/src/cairo-region.c
    trunk/Build/source/libs/cairo/cairo-src/src/cairo-scaled-font-private.h
    trunk/Build/source/libs/cairo/cairo-src/src/cairo-scaled-font-subsets.c
    trunk/Build/source/libs/cairo/cairo-src/src/cairo-scaled-font.c
    trunk/Build/source/libs/cairo/cairo-src/src/cairo-script-surface.c
    trunk/Build/source/libs/cairo/cairo-src/src/cairo-spans-private.h
    trunk/Build/source/libs/cairo/cairo-src/src/cairo-spans.c
    trunk/Build/source/libs/cairo/cairo-src/src/cairo-stroke-style.c
    trunk/Build/source/libs/cairo/cairo-src/src/cairo-surface-backend-private.h
    trunk/Build/source/libs/cairo/cairo-src/src/cairo-surface-observer.c
    trunk/Build/source/libs/cairo/cairo-src/src/cairo-surface-private.h
    trunk/Build/source/libs/cairo/cairo-src/src/cairo-surface-snapshot.c
    trunk/Build/source/libs/cairo/cairo-src/src/cairo-surface-subsurface.c
    trunk/Build/source/libs/cairo/cairo-src/src/cairo-surface-wrapper-private.h
    trunk/Build/source/libs/cairo/cairo-src/src/cairo-surface-wrapper.c
    trunk/Build/source/libs/cairo/cairo-src/src/cairo-surface.c
    trunk/Build/source/libs/cairo/cairo-src/src/cairo-svg-surface-private.h
    trunk/Build/source/libs/cairo/cairo-src/src/cairo-svg-surface.c
    trunk/Build/source/libs/cairo/cairo-src/src/cairo-svg.h
    trunk/Build/source/libs/cairo/cairo-src/src/cairo-tee-surface.c
    trunk/Build/source/libs/cairo/cairo-src/src/cairo-tor-scan-converter.c
    trunk/Build/source/libs/cairo/cairo-src/src/cairo-tor22-scan-converter.c
    trunk/Build/source/libs/cairo/cairo-src/src/cairo-toy-font-face.c
    trunk/Build/source/libs/cairo/cairo-src/src/cairo-traps.c
    trunk/Build/source/libs/cairo/cairo-src/src/cairo-tristrip.c
    trunk/Build/source/libs/cairo/cairo-src/src/cairo-truetype-subset.c
    trunk/Build/source/libs/cairo/cairo-src/src/cairo-type1-fallback.c
    trunk/Build/source/libs/cairo/cairo-src/src/cairo-type1-subset.c
    trunk/Build/source/libs/cairo/cairo-src/src/cairo-type3-glyph-surface.c
    trunk/Build/source/libs/cairo/cairo-src/src/cairo-types-private.h
    trunk/Build/source/libs/cairo/cairo-src/src/cairo-unicode.c
    trunk/Build/source/libs/cairo/cairo-src/src/cairo-user-font.c
    trunk/Build/source/libs/cairo/cairo-src/src/cairo-version.c
    trunk/Build/source/libs/cairo/cairo-src/src/cairo-vg-surface.c
    trunk/Build/source/libs/cairo/cairo-src/src/cairo-vg.h
    trunk/Build/source/libs/cairo/cairo-src/src/cairo-win32.h
    trunk/Build/source/libs/cairo/cairo-src/src/cairo-xcb-connection.c
    trunk/Build/source/libs/cairo/cairo-src/src/cairo-xcb-screen.c
    trunk/Build/source/libs/cairo/cairo-src/src/cairo-xcb-shm.c
    trunk/Build/source/libs/cairo/cairo-src/src/cairo-xcb-surface-core.c
    trunk/Build/source/libs/cairo/cairo-src/src/cairo-xcb-surface-render.c
    trunk/Build/source/libs/cairo/cairo-src/src/cairo-xcb-surface.c
    trunk/Build/source/libs/cairo/cairo-src/src/cairo-xlib-core-compositor.c
    trunk/Build/source/libs/cairo/cairo-src/src/cairo-xlib-display.c
    trunk/Build/source/libs/cairo/cairo-src/src/cairo-xlib-private.h
    trunk/Build/source/libs/cairo/cairo-src/src/cairo-xlib-render-compositor.c
    trunk/Build/source/libs/cairo/cairo-src/src/cairo-xlib-screen.c
    trunk/Build/source/libs/cairo/cairo-src/src/cairo-xlib-source.c
    trunk/Build/source/libs/cairo/cairo-src/src/cairo-xlib-surface-shm.c
    trunk/Build/source/libs/cairo/cairo-src/src/cairo-xlib-surface.c
    trunk/Build/source/libs/cairo/cairo-src/src/cairo-xlib-visual.c
    trunk/Build/source/libs/cairo/cairo-src/src/cairo-xlib-xcb-surface.c
    trunk/Build/source/libs/cairo/cairo-src/src/cairo-xml-surface.c
    trunk/Build/source/libs/cairo/cairo-src/src/cairo.c
    trunk/Build/source/libs/cairo/cairo-src/src/cairo.h
    trunk/Build/source/libs/cairo/cairo-src/src/cairoint.h
    trunk/Build/source/libs/cairo/cairo-src/src/test-compositor-surface.c
    trunk/Build/source/libs/cairo/cairo-src/src/test-null-compositor-surface.c
    trunk/Build/source/libs/cairo/cairo-src/src/test-paginated-surface.c
    trunk/Build/source/libs/cairo/configure
    trunk/Build/source/libs/cairo/version.ac

Added Paths:
-----------
    trunk/Build/source/libs/cairo/cairo-src/src/cairo-pdf-interchange.c
    trunk/Build/source/libs/cairo/cairo-src/src/cairo-tag-attributes-private.h
    trunk/Build/source/libs/cairo/cairo-src/src/cairo-tag-attributes.c
    trunk/Build/source/libs/cairo/cairo-src/src/cairo-tag-stack-private.h
    trunk/Build/source/libs/cairo/cairo-src/src/cairo-tag-stack.c

Removed Paths:
-------------
    trunk/Build/source/libs/cairo/cairo-src/src/cairo-skia.h

Modified: trunk/Build/source/libs/README
===================================================================
--- trunk/Build/source/libs/README	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/README	2018-10-20 03:19:36 UTC (rev 48952)
@@ -9,7 +9,7 @@
 
 See also comments in ../texk/README.
 
-cairo 1.14.12 - checked 07dec17
+cairo 1.16.0 - checked 20oct18
   http://cairographics.org/releases/
 
 freetype2 2.9.1 - checked 04may18

Modified: trunk/Build/source/libs/cairo/ChangeLog
===================================================================
--- trunk/Build/source/libs/cairo/ChangeLog	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/ChangeLog	2018-10-20 03:19:36 UTC (rev 48952)
@@ -1,3 +1,8 @@
+2018-10-20  Akira Kakuto  <kakuto at fuk.kindai.ac.jp>
+
+	Import cairo-1.16.0.
+	* Makefile.am, version.ac: Adapted.
+
 2017-12-07  Akira Kakuto  <kakuto at fuk.kindai.ac.jp>
 
 	Import cairo-1.14.12.

Modified: trunk/Build/source/libs/cairo/Makefile.am
===================================================================
--- trunk/Build/source/libs/cairo/Makefile.am	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/Makefile.am	2018-10-20 03:19:36 UTC (rev 48952)
@@ -98,6 +98,7 @@
 	@CAIRO_TREE@/src/cairo-path-stroke-traps.c \
 	@CAIRO_TREE@/src/cairo-path-stroke-tristrip.c \
 	@CAIRO_TREE@/src/cairo-pattern.c \
+	@CAIRO_TREE@/src/cairo-pdf-interchange.c \
 	@CAIRO_TREE@/src/cairo-pen.c \
 	@CAIRO_TREE@/src/cairo-polygon.c \
 	@CAIRO_TREE@/src/cairo-polygon-intersect.c \
@@ -124,6 +125,8 @@
 	@CAIRO_TREE@/src/cairo-surface-snapshot.c \
 	@CAIRO_TREE@/src/cairo-surface-subsurface.c \
 	@CAIRO_TREE@/src/cairo-surface-wrapper.c \
+	@CAIRO_TREE@/src/cairo-tag-attributes.c \
+	@CAIRO_TREE@/src/cairo-tag-stack.c \
 	@CAIRO_TREE@/src/cairo-time.c \
 	@CAIRO_TREE@/src/cairo-tor-scan-converter.c \
 	@CAIRO_TREE@/src/cairo-tor22-scan-converter.c \

Modified: trunk/Build/source/libs/cairo/Makefile.in
===================================================================
--- trunk/Build/source/libs/cairo/Makefile.in	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/Makefile.in	2018-10-20 03:19:36 UTC (rev 48952)
@@ -234,8 +234,9 @@
 	@CAIRO_TREE@/src/cairo-path-stroke-polygon.c \
 	@CAIRO_TREE@/src/cairo-path-stroke-traps.c \
 	@CAIRO_TREE@/src/cairo-path-stroke-tristrip.c \
-	@CAIRO_TREE@/src/cairo-pattern.c @CAIRO_TREE@/src/cairo-pen.c \
-	@CAIRO_TREE@/src/cairo-polygon.c \
+	@CAIRO_TREE@/src/cairo-pattern.c \
+	@CAIRO_TREE@/src/cairo-pdf-interchange.c \
+	@CAIRO_TREE@/src/cairo-pen.c @CAIRO_TREE@/src/cairo-polygon.c \
 	@CAIRO_TREE@/src/cairo-polygon-intersect.c \
 	@CAIRO_TREE@/src/cairo-polygon-reduce.c \
 	@CAIRO_TREE@/src/cairo-raster-source-pattern.c \
@@ -258,6 +259,8 @@
 	@CAIRO_TREE@/src/cairo-surface-snapshot.c \
 	@CAIRO_TREE@/src/cairo-surface-subsurface.c \
 	@CAIRO_TREE@/src/cairo-surface-wrapper.c \
+	@CAIRO_TREE@/src/cairo-tag-attributes.c \
+	@CAIRO_TREE@/src/cairo-tag-stack.c \
 	@CAIRO_TREE@/src/cairo-time.c \
 	@CAIRO_TREE@/src/cairo-tor-scan-converter.c \
 	@CAIRO_TREE@/src/cairo-tor22-scan-converter.c \
@@ -426,6 +429,7 @@
 	@CAIRO_TREE@/src/cairo-path-stroke-traps.$(OBJEXT) \
 	@CAIRO_TREE@/src/cairo-path-stroke-tristrip.$(OBJEXT) \
 	@CAIRO_TREE@/src/cairo-pattern.$(OBJEXT) \
+	@CAIRO_TREE@/src/cairo-pdf-interchange.$(OBJEXT) \
 	@CAIRO_TREE@/src/cairo-pen.$(OBJEXT) \
 	@CAIRO_TREE@/src/cairo-polygon.$(OBJEXT) \
 	@CAIRO_TREE@/src/cairo-polygon-intersect.$(OBJEXT) \
@@ -452,6 +456,8 @@
 	@CAIRO_TREE@/src/cairo-surface-snapshot.$(OBJEXT) \
 	@CAIRO_TREE@/src/cairo-surface-subsurface.$(OBJEXT) \
 	@CAIRO_TREE@/src/cairo-surface-wrapper.$(OBJEXT) \
+	@CAIRO_TREE@/src/cairo-tag-attributes.$(OBJEXT) \
+	@CAIRO_TREE@/src/cairo-tag-stack.$(OBJEXT) \
 	@CAIRO_TREE@/src/cairo-time.$(OBJEXT) \
 	@CAIRO_TREE@/src/cairo-tor-scan-converter.$(OBJEXT) \
 	@CAIRO_TREE@/src/cairo-tor22-scan-converter.$(OBJEXT) \
@@ -570,6 +576,7 @@
 	@CAIRO_TREE@/src/$(DEPDIR)/cairo-path-stroke.Po \
 	@CAIRO_TREE@/src/$(DEPDIR)/cairo-path.Po \
 	@CAIRO_TREE@/src/$(DEPDIR)/cairo-pattern.Po \
+	@CAIRO_TREE@/src/$(DEPDIR)/cairo-pdf-interchange.Po \
 	@CAIRO_TREE@/src/$(DEPDIR)/cairo-pen.Po \
 	@CAIRO_TREE@/src/$(DEPDIR)/cairo-png.Po \
 	@CAIRO_TREE@/src/$(DEPDIR)/cairo-polygon-intersect.Po \
@@ -601,6 +608,8 @@
 	@CAIRO_TREE@/src/$(DEPDIR)/cairo-surface-wrapper.Po \
 	@CAIRO_TREE@/src/$(DEPDIR)/cairo-surface.Po \
 	@CAIRO_TREE@/src/$(DEPDIR)/cairo-svg-surface.Po \
+	@CAIRO_TREE@/src/$(DEPDIR)/cairo-tag-attributes.Po \
+	@CAIRO_TREE@/src/$(DEPDIR)/cairo-tag-stack.Po \
 	@CAIRO_TREE@/src/$(DEPDIR)/cairo-time.Po \
 	@CAIRO_TREE@/src/$(DEPDIR)/cairo-tor-scan-converter.Po \
 	@CAIRO_TREE@/src/$(DEPDIR)/cairo-tor22-scan-converter.Po \
@@ -1132,8 +1141,9 @@
 	@CAIRO_TREE@/src/cairo-path-stroke-polygon.c \
 	@CAIRO_TREE@/src/cairo-path-stroke-traps.c \
 	@CAIRO_TREE@/src/cairo-path-stroke-tristrip.c \
-	@CAIRO_TREE@/src/cairo-pattern.c @CAIRO_TREE@/src/cairo-pen.c \
-	@CAIRO_TREE@/src/cairo-polygon.c \
+	@CAIRO_TREE@/src/cairo-pattern.c \
+	@CAIRO_TREE@/src/cairo-pdf-interchange.c \
+	@CAIRO_TREE@/src/cairo-pen.c @CAIRO_TREE@/src/cairo-polygon.c \
 	@CAIRO_TREE@/src/cairo-polygon-intersect.c \
 	@CAIRO_TREE@/src/cairo-polygon-reduce.c \
 	@CAIRO_TREE@/src/cairo-raster-source-pattern.c \
@@ -1156,6 +1166,8 @@
 	@CAIRO_TREE@/src/cairo-surface-snapshot.c \
 	@CAIRO_TREE@/src/cairo-surface-subsurface.c \
 	@CAIRO_TREE@/src/cairo-surface-wrapper.c \
+	@CAIRO_TREE@/src/cairo-tag-attributes.c \
+	@CAIRO_TREE@/src/cairo-tag-stack.c \
 	@CAIRO_TREE@/src/cairo-time.c \
 	@CAIRO_TREE@/src/cairo-tor-scan-converter.c \
 	@CAIRO_TREE@/src/cairo-tor22-scan-converter.c \
@@ -1460,6 +1472,9 @@
 @CAIRO_TREE@/src/cairo-pattern.$(OBJEXT):  \
 	@CAIRO_TREE@/src/$(am__dirstamp) \
 	@CAIRO_TREE@/src/$(DEPDIR)/$(am__dirstamp)
+ at CAIRO_TREE@/src/cairo-pdf-interchange.$(OBJEXT):  \
+	@CAIRO_TREE@/src/$(am__dirstamp) \
+	@CAIRO_TREE@/src/$(DEPDIR)/$(am__dirstamp)
 @CAIRO_TREE@/src/cairo-pen.$(OBJEXT):  \
 	@CAIRO_TREE@/src/$(am__dirstamp) \
 	@CAIRO_TREE@/src/$(DEPDIR)/$(am__dirstamp)
@@ -1538,6 +1553,12 @@
 @CAIRO_TREE@/src/cairo-surface-wrapper.$(OBJEXT):  \
 	@CAIRO_TREE@/src/$(am__dirstamp) \
 	@CAIRO_TREE@/src/$(DEPDIR)/$(am__dirstamp)
+ at CAIRO_TREE@/src/cairo-tag-attributes.$(OBJEXT):  \
+	@CAIRO_TREE@/src/$(am__dirstamp) \
+	@CAIRO_TREE@/src/$(DEPDIR)/$(am__dirstamp)
+ at CAIRO_TREE@/src/cairo-tag-stack.$(OBJEXT):  \
+	@CAIRO_TREE@/src/$(am__dirstamp) \
+	@CAIRO_TREE@/src/$(DEPDIR)/$(am__dirstamp)
 @CAIRO_TREE@/src/cairo-time.$(OBJEXT):  \
 	@CAIRO_TREE@/src/$(am__dirstamp) \
 	@CAIRO_TREE@/src/$(DEPDIR)/$(am__dirstamp)
@@ -1790,6 +1811,7 @@
 @AMDEP_TRUE@@am__include@ @am__quote@@CAIRO_TREE@/src/$(DEPDIR)/cairo-path-stroke.Po at am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@@CAIRO_TREE@/src/$(DEPDIR)/cairo-path.Po at am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@@CAIRO_TREE@/src/$(DEPDIR)/cairo-pattern.Po at am__quote@ # am--include-marker
+ at AMDEP_TRUE@@am__include@ @am__quote@@CAIRO_TREE@/src/$(DEPDIR)/cairo-pdf-interchange.Po at am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@@CAIRO_TREE@/src/$(DEPDIR)/cairo-pen.Po at am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@@CAIRO_TREE@/src/$(DEPDIR)/cairo-png.Po at am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@@CAIRO_TREE@/src/$(DEPDIR)/cairo-polygon-intersect.Po at am__quote@ # am--include-marker
@@ -1821,6 +1843,8 @@
 @AMDEP_TRUE@@am__include@ @am__quote@@CAIRO_TREE@/src/$(DEPDIR)/cairo-surface-wrapper.Po at am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@@CAIRO_TREE@/src/$(DEPDIR)/cairo-surface.Po at am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@@CAIRO_TREE@/src/$(DEPDIR)/cairo-svg-surface.Po at am__quote@ # am--include-marker
+ at AMDEP_TRUE@@am__include@ @am__quote@@CAIRO_TREE@/src/$(DEPDIR)/cairo-tag-attributes.Po at am__quote@ # am--include-marker
+ at AMDEP_TRUE@@am__include@ @am__quote@@CAIRO_TREE@/src/$(DEPDIR)/cairo-tag-stack.Po at am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@@CAIRO_TREE@/src/$(DEPDIR)/cairo-time.Po at am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@@CAIRO_TREE@/src/$(DEPDIR)/cairo-tor-scan-converter.Po at am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@@CAIRO_TREE@/src/$(DEPDIR)/cairo-tor22-scan-converter.Po at am__quote@ # am--include-marker
@@ -2480,6 +2504,7 @@
 	-rm -f @CAIRO_TREE@/src/$(DEPDIR)/cairo-path-stroke.Po
 	-rm -f @CAIRO_TREE@/src/$(DEPDIR)/cairo-path.Po
 	-rm -f @CAIRO_TREE@/src/$(DEPDIR)/cairo-pattern.Po
+	-rm -f @CAIRO_TREE@/src/$(DEPDIR)/cairo-pdf-interchange.Po
 	-rm -f @CAIRO_TREE@/src/$(DEPDIR)/cairo-pen.Po
 	-rm -f @CAIRO_TREE@/src/$(DEPDIR)/cairo-png.Po
 	-rm -f @CAIRO_TREE@/src/$(DEPDIR)/cairo-polygon-intersect.Po
@@ -2511,6 +2536,8 @@
 	-rm -f @CAIRO_TREE@/src/$(DEPDIR)/cairo-surface-wrapper.Po
 	-rm -f @CAIRO_TREE@/src/$(DEPDIR)/cairo-surface.Po
 	-rm -f @CAIRO_TREE@/src/$(DEPDIR)/cairo-svg-surface.Po
+	-rm -f @CAIRO_TREE@/src/$(DEPDIR)/cairo-tag-attributes.Po
+	-rm -f @CAIRO_TREE@/src/$(DEPDIR)/cairo-tag-stack.Po
 	-rm -f @CAIRO_TREE@/src/$(DEPDIR)/cairo-time.Po
 	-rm -f @CAIRO_TREE@/src/$(DEPDIR)/cairo-tor-scan-converter.Po
 	-rm -f @CAIRO_TREE@/src/$(DEPDIR)/cairo-tor22-scan-converter.Po
@@ -2672,6 +2699,7 @@
 	-rm -f @CAIRO_TREE@/src/$(DEPDIR)/cairo-path-stroke.Po
 	-rm -f @CAIRO_TREE@/src/$(DEPDIR)/cairo-path.Po
 	-rm -f @CAIRO_TREE@/src/$(DEPDIR)/cairo-pattern.Po
+	-rm -f @CAIRO_TREE@/src/$(DEPDIR)/cairo-pdf-interchange.Po
 	-rm -f @CAIRO_TREE@/src/$(DEPDIR)/cairo-pen.Po
 	-rm -f @CAIRO_TREE@/src/$(DEPDIR)/cairo-png.Po
 	-rm -f @CAIRO_TREE@/src/$(DEPDIR)/cairo-polygon-intersect.Po
@@ -2703,6 +2731,8 @@
 	-rm -f @CAIRO_TREE@/src/$(DEPDIR)/cairo-surface-wrapper.Po
 	-rm -f @CAIRO_TREE@/src/$(DEPDIR)/cairo-surface.Po
 	-rm -f @CAIRO_TREE@/src/$(DEPDIR)/cairo-svg-surface.Po
+	-rm -f @CAIRO_TREE@/src/$(DEPDIR)/cairo-tag-attributes.Po
+	-rm -f @CAIRO_TREE@/src/$(DEPDIR)/cairo-tag-stack.Po
 	-rm -f @CAIRO_TREE@/src/$(DEPDIR)/cairo-time.Po
 	-rm -f @CAIRO_TREE@/src/$(DEPDIR)/cairo-tor-scan-converter.Po
 	-rm -f @CAIRO_TREE@/src/$(DEPDIR)/cairo-tor22-scan-converter.Po

Modified: trunk/Build/source/libs/cairo/README
===================================================================
--- trunk/Build/source/libs/cairo/README	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/README	2018-10-20 03:19:36 UTC (rev 48952)
@@ -1,4 +1,4 @@
-	Building cairo-1.14.12 as part of the TL tree
+	Building cairo-1.16.0 as part of the TL tree
 	============================================
 
 This directory libs/cairo/ uses a proxy Makefile.am to build the cairo
@@ -12,4 +12,4 @@
 
 2012-11-10	Taco Hoekwater <taco at metatex.org>
 2013-04-15	Peter Breitenlohner <peb at mppmu.mpg.de>
-2017-12-07	Akira Kakuto <kakuto at fuk.kindai.ac.jp>
+2018-10-20	Akira Kakuto <kakuto at fuk.kindai.ac.jp>

Modified: trunk/Build/source/libs/cairo/TLpatches/ChangeLog
===================================================================
--- trunk/Build/source/libs/cairo/TLpatches/ChangeLog	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/TLpatches/ChangeLog	2018-10-20 03:19:36 UTC (rev 48952)
@@ -1,3 +1,7 @@
+2018-10-20  Akira Kakuto  <kakuto at fuk.kindai.ac.jp>
+
+	Import cairo-1.16.0.
+
 2017-12-07  Akira Kakuto  <kakuto at fuk.kindai.ac.jp>
 
 	Import cairo-1.14.12.

Modified: trunk/Build/source/libs/cairo/TLpatches/TL-Changes
===================================================================
--- trunk/Build/source/libs/cairo/TLpatches/TL-Changes	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/TLpatches/TL-Changes	2018-10-20 03:19:36 UTC (rev 48952)
@@ -1,5 +1,5 @@
-Changes applied to the cairo-1.14.12/ tree as obtained from:
-	http://cairographics.org/releases/cairo-1.14.12.tar.xz
+Changes applied to the cairo-1.16.0/ tree as obtained from:
+	http://cairographics.org/releases/cairo-1.16.0.tar.xz
 
 Removed:
 	Makefile.in
@@ -27,7 +27,6 @@
 	doc
 	perf
 	src/drm
-	src/skia
 	src/win32
 	test
 	util

Modified: trunk/Build/source/libs/cairo/cairo-src/BUGS
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/BUGS	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/BUGS	2018-10-20 03:19:36 UTC (rev 48952)
@@ -12,7 +12,7 @@
    up on previous bug reports, and search for existing, known
    bugs. Just use the "cairo" product:
 
-	http://bugs.freedesktop.org
+	https://bugs.freedesktop.org
 
    It is necessary to go through a quick account creation process,
    (with email address verification), in order to be able to report
@@ -26,7 +26,7 @@
    mailing list only allows posting from subscribers, so use the
    following page for subscription instructions:
 
-	http://cairographics.org/lists
+	https://cairographics.org/lists
 
    Again, we apologize for any inconvenience this subscription step
    might cause, but we've found it necessary to require this in order
@@ -49,10 +49,10 @@
 
 1) Check to see if the bug has been reported already. It's pretty easy
    to run a search or two against the cairo product in the
-   http://bugs.freedesktop.org bugzilla database. Another place to
+   https://bugs.freedesktop.org bugzilla database. Another place to
    look for known bugs is the cairo ROADMAP:
 
-	http://cairographics.org/ROADMAP
+	https://cairographics.org/ROADMAP
 
    which shows a planned schedule of releases and which bug fixes are
    being planned for each release.

Modified: trunk/Build/source/libs/cairo/cairo-src/HACKING
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/HACKING	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/HACKING	2018-10-20 03:19:36 UTC (rev 48952)
@@ -24,7 +24,7 @@
 Various ways to get in touch with other cairo developers and maintainers
 have been enumerated at:
 
-	http://cairographics.org/contact/
+	https://cairographics.org/contact/
 
 Most of that information is also reflected in the following sections.
 
@@ -35,7 +35,7 @@
 There are various mailing lists that are useful when developing cairo
 code.  A complete list is always available at:
 
-	http://cairographics.org/lists/
+	https://cairographics.org/lists/
 
 It is recommended that cairo developers subscribe to all those lists.
 The cairo list by itself generates much more traffic than the others
@@ -48,7 +48,7 @@
 
 We use a standard bugzilla bug tracking system available at:
 
-	http://bugs.freedesktop.org/
+	https://bugs.freedesktop.org/
 
 See file named BUGS for detailed information on reporting bugs.  In short,
 for straight bug reports, it's best to report them there such that they
@@ -71,11 +71,11 @@
 
 We use /git/ for version control.  See:
 
-	http://cairographics.org/download/
+	https://cairographics.org/download/
 
 For more information on using git, see:
 
-	http://freedesktop.org/wiki/Infrastructure/git/
+	https://freedesktop.org/wiki/Infrastructure/git/
 
 
 Build System
@@ -165,7 +165,7 @@
 For more documentation including frequently asked questions, tutorials,
 samples, roadmap, todo list, etc visit:
 
-	http://cairographics.org/documentation/
+	https://cairographics.org/documentation/
 
 Some of those should gradually be moved to doc/.
 

Modified: trunk/Build/source/libs/cairo/cairo-src/INSTALL
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/INSTALL	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/INSTALL	2018-10-20 03:19:36 UTC (rev 48952)
@@ -140,11 +140,11 @@
 However, if you don't need such a bleeding-edge version of cairo, then
 you might prefer to start by building the latest stable cairo release:
 
-	http://cairographics.org/releases
+	https://cairographics.org/releases
 
 or perhaps the latest (unstable) development snapshot:
 
-	http://cairographics.org/snapshots
+	https://cairographics.org/snapshots
 
 There you'll find nicely packaged tar files that include a configure
 script so you can go back the the simpler instructions above.

Modified: trunk/Build/source/libs/cairo/cairo-src/NEWS
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/NEWS	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/NEWS	2018-10-20 03:19:36 UTC (rev 48952)
@@ -1,16 +1,187 @@
-Release 1.14.12   (2017-06-13  Bryce Harrington <bryce at osg.samsung.com>)
+Release 1.16.0 (2018-10-19 Bryce Harrington <bryce at bryceharrington.org>)
 ========================================================================
-Another bugfix release rolling up backported fixes for the past half year.
+This new stable release incorporates a number of improvements made in
+the four years since 1.14.0.
 
-For a complete log of changes since 1.14.10, please see:
+Of particular note is a wealth of work by Adrian Johnson to enhance PDF
+functionality, including restoring support for MacOSX 10.4, metadata,
+hyperlinks, and more.
 
-    http://cairographics.org/releases/ChangeLog.cairo-1.14.12
+Much attention also went into fonts, including new colored emoji glyph
+support, variable fonts, and fixes for various font idiosyncrasies.
 
+Other noteworthy changes include GLESv3 support for the cairo_gl
+backend, tracking of SVG units in generated SVG documents, and cleanups
+for numerous test failures and related issues in the PDF and Postscript
+backends.
 
-Features
---------
+For a complete log of changes, please see
+
+    https://cairographics.org/releases/ChangeLog.1.16.0
+
+
+Features and Enhancements
+-------------------------
+* Add support for OpenGL ES 3.0 to the gl backend.
+* The PDF backend has gained support for a range of widely used
+  features, including thumbnails, page labels, metadata, document
+  outlines, structured text, hyperlinks, and tags.  Tags permit adding
+  logical info such as headings, tables, figures, etc. that facilitates
+  indexing, accessibility, text reflow, searching, and extraction of the
+  tagged items to other software.  For details on this new PDF
+  functionality, see:
+    https://lists.cairographics.org/archives/cairo/2016-June/027427.html
+* Variable font support.  Variable fonts are single font files with
+  various typography characteristics, such as weight or slant, that users
+  of the font can adjust between two points.  Effectively this enables a
+  single font to behave as multiple fonts.
+* Restore MacOSX 10.4 support.  Cairo had dropped 10.4 support when
+  moving to the CoreText API.  Now we automatically detect which API to
+  use via dynamic linking, so can resume supporting this older version
+  of MacOSX.
+* Support colored emoji glyphs, stored as PNG images in OpenType fonts.
+* Skia backend is removed
+* Use Reusable streams for forms in Level 3 Postscript.
+* Add CAIRO_MIME_TYPE_EPS mime type for embedding EPS files.
+* Add CCITT_FAX mime type for PDF and PS surfaces
+* svg: add a new function to specify the SVG document unit
+  (Bug #90166)
+* Use UTF-8 filenames on Windows
+
+
+API Changes
+-----------
+Several new APIs were added.  No existing APIs were altered.
+
+New PDF functionality:
+
+  * cairo_pdf_surface_add_outline
+  * cairo_pdf_surface_set_metadata
+  * cairo_pdf_surface_set_page_label
+  * cairo_pdf_surface_set_thumbnail_size
+  * cairo_tag_begin
+  * cairo_tag_end
+  * CAIRO_STATUS_TAG_ERROR
+
+New error status items for problems relating to PDF tagging:
+
+  * CAIRO_STATUS_WIN32_GDI_ERROR
+  * CAIRO_STATUS_FREETYPE_ERROR
+  * CAIRO_STATUS_PNG_ERROR
+
+    New error status items for handling of GDI, libfreetype, and libpng
+    errors, respectively.
+
+
+Setting up Win32 surfaces for HDC with alpha channels:
+
+  * cairo_win32_surface_create_with_format
+
+    New API for added PDF functionality (see above), and new error
+    status item for problems relating to PDF tagging.
+
+Variable fonts:
+
+  * cairo_font_options_get_variations
+  * cairo_font_options_set_variations
+
+Tracking units in SVG documents:
+
+  * cairo_svg_surface_set_document_unit
+  * cairo_svg_surface_get_document_unit
+
+
+
+Dependency Changes
+------------------
 None
 
+
+Performance Optimizations
+-------------------------
+None
+
+
+Notable Bug Fixes
+-----------------
+* Fix thin lines that don't show up when printing in Inkscape due to
+  overly aggressive culling.
+  (Bug #77298)
+* Fix playback of recording surfaces into PDF surfaces, where objects
+  with negative coordinates were not getting drawn.  To address this,
+  the coordinate systems for PDF and PS have been changed to match
+  cairo's coordinate system.  This allows recording surfaces to be
+  emitted in cairo coordinates, and results in the same origin being
+  used for all operations when using the recording surface XObject.
+  Test cases for PDF and PS have also been updated accordingly.
+  (Bug #89232)
+* Fix "invalidfont" error on some printers when printing PDFs with
+  embedded fonts that have glyphs (such as spaces) with
+  num_contours == 0.  (Bug #79897)
+* Fix missing glyphs such as thin dashes, which get scaled to 0 in
+  userspace and thus have their drawing operations culled.  (Bug #94615)
+* Fix other oddities caused by variously idiosyncratic fonts.
+* Fix a data race in freed_pool discovered by Firefox's cairo usage.
+  The patch adads atomic int load and store functions, with relaxed
+  memory ordering.  (Bug #90318)
+* Handle SOURCE and CLEAR operators when painting color glyphs.
+  (Bug #102661)
+* Fix falling back to system font with PDFs using certain embedded
+  fonts, due to truncated font names.
+  (Bug #103249)
+* Prevent curved strokes in small ctms from being culled from vector
+  surfaces
+  (Bug #103071)
+* Fix assertion hit with PDFs using Type 4 fonts rendered with user
+  fonts, due to error when destroying glyph page.
+  (Bug #103335)
+* Prevent invalid ptr access for > 4GB images.
+  (Bug #98165)
+* pdf: Fix internal links pointing to other pages, by pre-calculating
+  page heights so that link positions can be calculated more accurately.
+* Fix error reporting in the xcb backend if fallback fails.  Instead of
+  returning NULL when the X11 server can't do some operation, return a
+  surface in an error state.
+* Clarify documentation regarding device scale inheritance and the units
+  used in cairo_surface_create_similar_image.
+  (Bug #99094)
+* Call XSync in the xlib backend before setting the error handler to
+  ignore errors for certain requests, to make sure all pending errors
+  are handled first.
+* Fix regression with text containing space character on Win32.
+  (Bug: https://gitlab.freedesktop.org/cairo/cairo/issues/339)
+
+For a more comprehensive listing of fixed bugs, see the release notes for the
+individual 1.15.x releases.
+
+
+Release 1.15.14    (2018-09-19 Bryce Harrington <bryce at bryceharrington.org>)
+============================================================================
+We're nearly ready to finalize the 1.16.0 release, so this snapshot
+can be considered a beta for 1.16.
+
+The most notable change this release is a performance optimization for
+windows, discussed below.  Other than that, much of the development
+focus was on final polish and stability as we prepare for 1.16.
+
+Some attention went into getting the testsuite passing at least for the
+image backend.  The Cairo testsuite depends on external software like
+Pixman, and changes in the rendering behavior of these dependencies
+change test behavior, leading to false positives.
+
+Results from the Coverity static testing tool were also reviewed.  Most
+of the issues flagged were false positives, but there were several
+legitimate problems found and fixed.
+
+For a complete log of changes, please see
+
+    https://cairographics.org/releases/ChangeLog.1.15.12
+
+Features and Enhancements
+-------------------------
+* Add more FreeeType font color conversions to support COLR/CPAL
+* Update test reference images against current pixman
+
 API Changes
 -----------
 None
@@ -21,39 +192,217 @@
 
 Performance Optimizations
 -------------------------
+Vasily Galkin introduced a Win32 performance optimization for
+CAIRO_OPERATOR_SOURCE when copying data from a backbuffer to an argb32
+surface corresponding to a Win32 DC.  With this, argb32 drawing should
+perform as fast as typical dibsection-buffered GDI drawing.  See the
+Cairo mailing list for April 2018 for data and discussion of the
+performance improvements.
+
+
+Bug Fixes
+---------
+* Fix crash when rendering Microsoft's Segoe UI Emoji Regular font.
+* Fix build breakage with glesv3 enabled due to non-existant glesv3.pc.
+* Fix memory leaks found by Coverity
+* Fix incorrect null ptr handling found by Coverity
+* Fix test compilation when font-config is disabled
+* Use _cairo_malloc instead of malloc (Bug #101547) (CVE-2017-9814)
+* Fix assertion failure in the freetype backend (Bug #105746)
+
+
+Release 1.15.12    (2018-04-04 Bryce Harrington <bryce at osg.samsung.com>)
+========================================================================
+The main focus for this release is the addition of Variable Font
+support.  Variable fonts are single font files with various typography
+characteristics, such as weight or slant, that users of the font can
+adjust between two points.  Effectively this enables a single font to
+behave as multiple fonts.
+
+The Skia backend is disabled in this release, due to severe bitrot, and
+will be removed in future releases.  Contact the cairo team if you have
+a need of this backend.
+
+For a complete log of changes, please see
+
+    https://cairographics.org/releases/ChangeLog.1.15.12
+
+Features and Enhancements
+-------------------------
+* Variable font support
+* Skia backend is disabled
+
+API Changes
+-----------
+* cairo_font_options_get_variations() and
+  cairo_font_options_set_variations() are added.
+
+Dependency Changes
+------------------
 None
 
+Performance Optimizations
+-------------------------
+None
+
 Bug Fixes
 ---------
+* Fix errors in csi-trace --help and --version options
+* Fix a 'memory leak' in the image compositor, with
+  pixman_glyph_cache_t.
+* Fix access of uninitialized memory found by valgrind
+  (Bug #91271)
+* Fix improper initialization of memory in
+  _cairo_ft_font_face_create_for_pattern()
+  (Bug #105084)
+* Fix multi-monitor virtual desktop with negative coords on Win32
+  (Bug #100793)
+* Fix issues occuring with older FreeType versions.
+
+
+Release 1.15.10    (2017-12-07 Bryce Harrington <bryce at osg.samsung.com>)
+========================================================================
+This release adds GLESv3 support to the cairo_gl backend, adds
+tracking of SVG units in generated svg documents, and cleans up numerous
+test failures and related issues in the PDF and Postscript backends.
+
+For a complete log of changes, please see
+
+    https://cairographics.org/releases/ChangeLog.1.15.10
+
+Features and Enhancements
+-------------------------
+* Add support for OpenGL ES 3.0 to the gl backend.
+* Use Reusable streams for forms in Level 3 Postscript.
+* Add CAIRO_MIME_TYPE_EPS mime type for embedding EPS files.
+* Add CCITT_FAX mime type for PDF and PS surfaces
+* svg: add a new function to specify the SVG document unit
+  (Bug #90166)
+* Use UTF-8 filenames on Windows
+
+API Changes
+-----------
+* cairo_svg_surface_set_document_unit() and
+  cairo_svg_surface_get_document_unit()
+
+Dependency Changes
+------------------
+None
+
+Performance Optimizations
+-------------------------
+None
+
+Bug Fixes
+---------
+* Fix regression in gles version detection
+* Fix undefined-behavior with integer math.
+* Handle SOURCE and CLEAR operators when painting color glyphs.
+  (Bug #102661)
+* Convert images to rgba or a8 formats when uploading with GLESv2
+* Use _WIN32 instead of windows.h to check for windows build.
+* Fix sigabrt printing documents with fonts lacking the mandatory .nodef
+  glyph.
+  (Bug #102922)
+* Prevent curved strokes in small ctms from being culled from vector
+  surfaces
+  (Bug #103071)
+* Fix painting an unbounded recording surface with the SVG backend.
+* Fix falling back to system font with PDFs using certain embedded
+  fonts, due to truncated font names.
+  (Bug #103249)
+* Fix handling of truetype fonts with excessively long font names
+  (Bug #103249)
+* Fix race conditions with cairo_mask_compositor_t
+  (Bug #103037)
+* Fix build error with util/font-view
 * Fix assertion hit with PDFs using Type 4 fonts rendered with user
   fonts, due to error when destroying glyph page.
   (Bug #103335)
-* Fix build error with util/font-view
-* Fix handling of truetype fonts with excessively long font names
-  (Bug #103249)
-* Fix falling back to system font with PDFs using certain embedded
-  fonts, due to truncated font names.
-  (Bug #103249)
-* Fix sigabrt printing documents with fonts lacking the mandatory .nodef
-  glyph.
-  (Bug #102922)
-* Fix undefined-behavior with integer math.
-* Fix various warnings and typos
+* Set default creation date for PDFs
+* Prevent invalid ptr access for > 4GB images.
+  (Bug #98165)
+* Prevent self-copy infinite loop in Postscript surface.
+* Fix padded image crash in Postscript surface.
+* Fix annotation bugs in PDFs and related memory leaks
+* Fix test failures and other assorted issues in ps and pdf code.
+* Fix code generation when using GCC legacy atomic operations
+  (Bug #103559)
+* Fix various compilation warnings and errors.
+* Fix various distcheck errors with private symbols, doxygen formatting,
+  etc.
 
-
-Release 1.14.10   (2017-06-13  Bryce Harrington <bryce at osg.samsung.com>)
+Release 1.15.8     (2017-08-29 Bryce Harrington <bryce at osg.samsung.com>)
 ========================================================================
-Bugfix release rolling up backported fixes for the past half year.
+This small snapshot provides new colored emoji glyph support, and a
+handful of minor fixes.
 
-For a complete log of changes since 1.14.8, please see:
+For a complete log of changes, please see
 
-    http://cairographics.org/releases/ChangeLog.cairo-1.14.10
+    https://cairographics.org/releases/ChangeLog.1.15.8
 
+Features and Enhancements
+-------------------------
+* Support colored emoji glyphs, stored as PNG images in OpenType fonts.
 
-Features
---------
+
+API Changes
+-----------
 None
 
+Dependency Changes
+------------------
+None
+
+Performance Optimizations
+-------------------------
+None
+
+Bug Fixes
+---------
+
+* pdf: Fix internal links pointing to other pages, by pre-calculating
+  page heights so that link positions can be calculated more accurately.
+
+* image: Fix crash on negative lengths
+
+* win32: Fix initialization of mutexes for static builds
+
+* pdf: Don't emit /PageLabel dict when no labels defined
+
+* font: Fix color font loading on big-endian systems
+
+* font:	Fix color font support infinite-loop with empty glyphs
+
+* Fix off by one check in cairo-image-info.c
+
+
+
+Release 1.15.6     (2017-06-13 Bryce Harrington <bryce at osg.samsung.com>)
+========================================================================
+This new snapshot incorporates changes over the past half-year since the
+1.15.4 snapshot, including all the fixes from the 1.14 release series.
+
+The PDF code continues to be enhanced, and we're restored MacOSX 10.4
+support.  Font-related fixes and improved error handling for X round out
+the release.
+
+For a complete log of changes, please see
+
+    https://cairographics.org/releases/ChangeLog.1.15.6
+
+
+Features and Enhancements
+-------------------------
+* Detect if variable fonts have	synthesized bold/italic	or non-default
+  variants, and	     use a fallback font where needed.
+
+* Restore MacOSX 10.4 support.	    Cairo had dropped 10.4 support when
+  moving to the CoreText API.  Now we automatically detect which API to
+  use via dynamic linking, so can resume supporting this older version
+  of MacOSX.
+
+
 API Changes
 -----------
 None
@@ -68,10 +417,6 @@
 
 Bug Fixes
 ---------
-* Clarify documentation	regarding device scale inheritance and the units
-  used in cairo_surface_create_similar_image.
-  Bug #99094.
-
 * Fix error reporting in the xcb backend if fallback fails.  Instead of
   returning NULL when the X11 server can't do some operation, return a
   surface in an error state.
@@ -80,40 +425,71 @@
   ignore errors for certain requests, to make sure all pending errors
   are handled first.
 
-* For opentype fonts, always use gid to lookup glyph.
+* Fix text-glyph-range for quartz-font.	 Use 0xFFFF instead of 0 for
+  invalid index	       tracking.
 
-* If glyph 0 used for rendering, remap to different index.
+* Fix handling of Supplementary Multilingual Plane (SMP) Unicode
+  characters in quartz-font.
 
-* Set font size to em size when retrieving unhinted metrics.
+* Fix various issues in the drm backend	including updating API usage and
+  general code cleanup.
 
-* Flush ASCII85Decode file after use with Postscript files.
+* Clarify documentation	regarding device scale inheritance and the units
+  used in cairo_surface_create_similar_image.
+  Bug #99094.
 
-* pdf: Don't fail subsetting if unable to convert utf8 to utf16.
 
-* For truetype, reverse cmap search should end when 0xffff- 0xffff range
-  reached.
+Release 1.15.4     (2016-12-9 Bryce Harrington <bryce at osg.samsung.com>)
+=======================================================================
+This new snapshot incorporates changes over the past year since the
+1.15.2 snapshot, including all the fixes from the 1.14 release series.
 
-* Fix bug in line wrapping with the PDF operators.
+Of particular note in this snapshot is a wealth of work by Adrian
+Johnson to enhance PDF support, as well as numerous bug fixes provided
+by him and other contributors.
 
-* Fix an off by one check in cairo-image-info.c.
+For a complete log of changes since the last release, please see:
 
+    https://cairographics.org/releases/ChangeLog.1.15.4
 
-Release 1.14.8    (2016-12-07  Bryce Harrington <bryce at osg.samsung.com>)
-========================================================================
-Bugfix release rolling up backported fixes for the past year.
+Features
+--------
+* The PDF backend has gained support for a range of widely used
+  features, including thumbnails, page labels, metadata, document
+  outlines, structured text, hyperlinks, and tags.  Tags permit adding
+  logical info such as headings, tables, figures, etc. that facilitates
+  indexing, accessibility, text reflow, searching, and extraction of the
+  tagged items to other software.  For details on this new PDF
+  functionality, see:
 
-For a complete log of changes since 1.14.6, please see:
+    https://lists.cairographics.org/archives/cairo/2016-June/027427.html
 
-    http://cairographics.org/releases/ChangeLog.cairo-1.14.8
 
-Features
---------
-None
-
 API Changes
 -----------
-None
 
+  cairo_win32_surface_create_with_format
+
+    Added a cairo API to set up Win32 surfaces for HDC with alpha channels.
+
+  cairo_pdf_surface_add_outline
+  cairo_pdf_surface_set_metadata
+  cairo_pdf_surface_set_page_label
+  cairo_pdf_surface_set_thumbnail_size
+  cairo_tag_begin
+  cairo_tag_end
+  CAIRO_STATUS_TAG_ERROR
+
+    New API for added PDF functionality (see above), and new error
+    status item for problems relating to PDF tagging.
+
+  CAIRO_STATUS_WIN32_GDI_ERROR
+  CAIRO_STATUS_FREETYPE_ERROR
+  CAIRO_STATUS_PNG_ERROR
+
+    New error status items for handling of GDI, libfreetype, and libpng
+    errors, respectively.
+
 Dependency Changes
 ------------------
 None
@@ -124,23 +500,132 @@
 
 Bug Fixes
 ---------
+* Bug fixes from 1.15.2 (see the 1.15.2 NEWS for details)
+
+* Fix playback of recording surfaces into PDF surfaces, where objects
+  with negative coordinates were not getting drawn.  To address this,
+  the coordinate systems for PDF and PS have been changed to match
+  cairo's coordinate system.  This allows recording surfaces to be
+  emitted in cairo coordinates, and results in the same origin being
+  used for all operations when using the recording surface XObject.
+  Test cases for PDF and PS have also been updated accordingly.
+  (Bug #89232)
+
 * Fix "invalidfont" error on some printers when printing PDFs with
   embedded fonts that have glyphs (such as spaces) with
   num_contours == 0.  (Bug #79897)
+
+* Fix missing glyphs such as thin dashes, which get scaled to 0 in
+  userspace and thus have their drawing operations culled.  (Bug #94615)
+
+* Fix other oddities caused by variously idiosyncratic fonts.
+
 * Fix deadlock when destruction of a scaled font indirectly triggers
   destruction of a second scaled font, causing the global cache to be
   locked twice.  (Bug #93891)
+
 * Fix X errors reported to applications when shmdt() is called before
   the Attach request is processed, due to missing xcb and xlib calls.
+
 * Fix random failure in record-paint-alpha-clip-mast test case, caused
   by an incorrect assumption that a deferred clear can be skipped.
   (Bug #84330)
+
 * Fix crash when dealing with an XShmGetImage() failure, caused by a
   double free in _get_image_surface().  (Bug #91967)
-* Fix build issue when using non-GNU strings utility.  (Bug #88639)
+
+* Fix invalid execution of ASCII85 data by the PS interpreter that the
+  image operator didn't use, by flushing the extraneous data after
+  drawing the image.  (Bug #84811)
+
+* Fix decoding of Adobe Photoshop's inverted CMYK JPEG files in PDF
+  export.
+
+* Fix unbounded surface assertion in win32-print code.
+
+* Fix a data race in freed_pool discovered by Firefox's cairo usage.
+  The patch adads atomic int load and store functions, with relaxed
+  memory ordering.  (Bug #90318)
+
 * Cleanup debugging text sent to stdout instead of log.  (Bug #95227)
 
+* Fix build issue when using non-GNU strings utility.  (Bug #88639)
 
+* Fix build of cairo modules as regular modules, not as versioned shared
+  libaries.  (Bug #29319)
+
+* Fix build on win32 using gcc 5.4.
+
+* Fix build of script backend to require zlib.
+
+* Update test suite reference images using Debian Jessie 64-bit and
+  poppler current as of June, 2016.
+
+* Various improvements to documentation and tests, compiler warning
+  fixes, and an assortment of code refactoring and cleanup.
+
+
+Release 1.15.2     (2015-12-10 Bryce Harrington <bryce at osg.samsung.com>)
+========================================================================
+This release is largely a rollup to include a variety of fixes that
+didn't make the cut for the stable 1.14.2 and 1.14.4 releases, as well
+as all the fixes from those releases.  Notably this includes a highly
+requested new API for Win32 surfaces.
+
+For a complete log of changes since the last release, please see:
+
+    https://cairographics.org/releases/ChangeLog.1.15.2
+
+Features
+--------
+None
+
+API Changes
+-----------
+
+  cairo_win32_surface_create_with_format
+
+    Added a cairo API to set up Win32 surfaces for HDC with alpha channels.
+
+Dependency Changes
+------------------
+None
+
+Performance Optimizations
+-------------------------
+None
+
+Bug Fixes
+---------
+* All the bug fixes from 1.14.2, 1.14.4, and 1.14.6
+
+* Fix xcb/xlib compilation and calls.  Make image boxes behave when SHM
+  is not available.
+
+* Fix various issues with printing and transparent images on Win32.
+
+* Fix thin lines that don't show up when printing in Inkscape due to
+  overly aggressive culling.
+  (Bug #77298)
+
+* Fix broken printing via pdf when glyph 0 is used for rendering,
+  resulting in missing spaces and letters.
+  (Bug #89082)
+
+* Fix crash for certain glyphs in opentype fonts.
+  (Bug #91902)
+
+* Fix incorrect rendering of SVG paths with more than one subpath.  If
+  more than one trap is passed in then it's guaranteed that the returned
+  traps will have their left edge to the left of their right edge, but
+  if only one trap is passed in then the function always returns without
+  doing anything.
+  (Bug #90984)
+
+* Improve rendering with Quartz to better match pixman's blending and
+  filtering behavior.
+
+
 Release 1.14.6    (2015-12-09  Bryce Harrington <bryce at osg.samsung.com>)
 ========================================================================
 Simple bugfix release to fix one Windows issue.
@@ -147,7 +632,7 @@
 
 For a complete log of changes since 1.14.4, please see:
 
-    http://cairographics.org/releases/ChangeLog.cairo-1.14.6
+    https://cairographics.org/releases/ChangeLog.1.14.6
 
 Features
 --------
@@ -182,10 +667,9 @@
 updates to documentation, etc.
 
 For a complete log of changes since 1.14.2, please see:
+ 
+    https://cairographics.org/releases/ChangeLog.cairo-1.14.4
 
-    http://cairographics.org/releases/ChangeLog.cairo-1.14.4
-
-
 Features
 --------
 None
@@ -260,7 +744,7 @@
   with XCB.
 
 
-Release 1.14.2 (2014-03-09 Bryce Harrington <bryce at osg.samsung.com>)
+Release 1.14.2 (2015-03-09 Bryce Harrington <bryce at osg.samsung.com>)
 ====================================================================
 This release provides collected bug fixes, along with one feature
 enhancement for the xcb backend, and a small performance improvement for
@@ -335,6 +819,7 @@
    (fdo bugs #89338, #89340, #89356, #89354)
  * Fix various documentation warnings and errors
 
+
 Release 1.14.0 (2014-10-13 Bryce Harrington <bryce at osg.samsung.com>)
 ====================================================================
 Hard to believe it's been over a year since our last release, but it's
@@ -836,7 +1321,7 @@
  and then back again to user coordinates (cairo_copy_path,
  cairo_append_path)
  https://bugs.freedesktop.org/show_bug.cgi?id=54732
- 
+
  Fix extents computations for a degenerate path consisting only of a
  move-to
  https://bugs.freedesktop.org/show_bug.cgi?id=54549
@@ -844,9 +1329,9 @@
  Prevent crashing on a degenerate project edge after polygon
  intersection
  https://bugs.freedesktop.org/show_bug.cgi?id=54822
- 
 
 
+
 Release 1.12.2 (2012-04-29 Chris Wilson <chris at chris-wilson.co.uk>)
 ===================================================================
 After such a long gestation period for the release of Cairo 1.12, we
@@ -864,7 +1349,7 @@
 
  Allow applications to create 0x0 xlib surfaces, such as used by LibreOffice.
  https://bugs.freedesktop.org/show_bug.cgi?id=49118
- 
+
  Trim composite extents for SOURCE/CLEAR operators to the mask.
 
  Use fallback fonts in PDF for unhandled computed glyph widths
@@ -1178,7 +1663,7 @@
 applications to understand issues and as a means for profiling
 real-world usage of cairo.
 
-The traces generated by cairo-trace have been collected in 
+The traces generated by cairo-trace have been collected in
 
   git://git.cairographics.org/git/cairo-traces
 
@@ -1394,8 +1879,8 @@
     The Cairo region API was actually added a couple of snapshots ago, but we
     forgot to mention it at the time. A simple API for the handling of
     rectangular pixel-aligned regions by Soeren Sandmann.
-  
 
+
 Backend-specific improvements
 -----------------------------
 cairo-gl
@@ -1599,10 +2084,10 @@
    QT
 
    OpenVG - The initial work was done by Øyvind Kolås, and made ready for
-            inclusion by Pierre Tardy.
+	    inclusion by Pierre Tardy.
 
    OpenGL - An advanced OpenGL compositor. The aim is to write a integrate
-            directed rendering using OpenGL at a high-level into Cairo. In
+	    directed rendering using OpenGL at a high-level into Cairo. In
 	    contrast to the previous attempt using Glitz which tried to
 	    implement the RENDER protocol on top of OpenGL, using the
 	    high-level interface should permit greater flexibility and
@@ -1801,7 +2286,7 @@
    Don't call FT_Done_Face() on faces we did not create
 
    zombie ft_font_face / ft_unscaled_font mutual referencing problems
-   http://bugs.freedesktop.org/show_bug.cgi?id=21706
+   https://bugs.freedesktop.org/show_bug.cgi?id=21706
 
 Ensure win32 font backend sets the return value to -1 (indicating the absent
 glyph) if the font index lookup for the unicode character fails. And
@@ -1808,7 +2293,7 @@
 similarly fix a bug where a fatal error was raised for an invalid glyph.
 
    cairo_scaled_font_glyph_extents breaks with invalid glyph id
-   http://bugs.freedesktop.org/show_bug.cgi?id=20255
+   https://bugs.freedesktop.org/show_bug.cgi?id=20255
 
 Various improvements to the documentation, reported by Truc Troung:
 
@@ -1838,7 +2323,7 @@
 Fix build of DirectFB backend with debugging enabled:
 
    Bug in _cairo_directfb_surface_release_source_image function
-   http://bugs.freedesktop.org/show_bug.cgi?id=18322
+   https://bugs.freedesktop.org/show_bug.cgi?id=18322
 
 Fix build on OS/2.
 
@@ -1856,12 +2341,12 @@
 
    Failed assertion `CAIRO_REFERENCE_COUNT_HAS_REFERENCE
    (&pattern->ref_count)' when using cairo quartz backend
-   http://bugs.freedesktop.org/show_bug.cgi?id=18632
+   https://bugs.freedesktop.org/show_bug.cgi?id=18632
 
 Invalid references to glyphs after early culling, causing segmentation faults
 in the PDF backend:
 
-   http://lists.cairographics.org/archives/cairo/2008-December/015976.html
+   https://lists.cairographics.org/archives/cairo/2008-December/015976.html
 
 Check for XRender in the XCB backend, or else we may attempt an invalid memory
 access:
@@ -1904,7 +2389,7 @@
 fonts in poppler (unsigned promotion fixes):
 
     Use cairo user-font for Type 3 fonts
-    http://lists.freedesktop.org/archives/poppler/2008-October/004181.html
+    https://lists.freedesktop.org/archives/poppler/2008-October/004181.html
 
 Avoid miscomputing size of fallback images required when rendering
 with CLEAR, IN, or SOURCE operator to vector surfaces, (PS, PDF, SVG,
@@ -1913,7 +2398,7 @@
 Be more tolerant of broken fonts when subsetting type1 fonts:
 
    Error handling in cairo_type1_font_subset_get_glyph_names_and_widths
-   http://lists.cairographics.org/archives/cairo/2008-October/015569.html
+   https://lists.cairographics.org/archives/cairo/2008-October/015569.html
 
 Fix cairo_fill_extents, cairo_stroke_extents, cairo_path_extents, to
 correctly allow NULL parameters as documented.
@@ -1983,10 +2468,10 @@
 and Chris Wilson):
 
 	Bad clipping with EXTEND_NONE
-	http://bugs.freedesktop.org/show_bug.cgi?id=15349
+	https://bugs.freedesktop.org/show_bug.cgi?id=15349
 
 	Improve filtering handling in cairo-pattern.c
-	http://bugs.freedesktop.org/show_bug.cgi?id=15367
+	https://bugs.freedesktop.org/show_bug.cgi?id=15367
 
 	Many thanks to Chris Wilson for digging out and cleaning up
 	these fixes.
@@ -2214,7 +2699,7 @@
 PS: Fix gradients with non-constant alpha (Chris Wilson)
 
 Fix deadlock in user-font code (Richard Hughes and Behdad Esfahbod)
-	http://bugs.freedesktop.org/show_bug.cgi?id=16819
+	https://bugs.freedesktop.org/show_bug.cgi?id=16819
 
 Countless other bugs have been fixed and optimizations made, many of
 them thanks to Chris Wilson. Thanks Chris and others!
@@ -2296,7 +2781,7 @@
 PS: Fix gradients with non-constant alpha (Chris Wilson)
 
 Fix deadlock in user-font code (Richard Hughes and Behdad Esfahbod)
-	http://bugs.freedesktop.org/show_bug.cgi?id=16819
+	https://bugs.freedesktop.org/show_bug.cgi?id=16819
 
 Several other minor fixes.
 
@@ -2557,10 +3042,10 @@
 Xerox and Dell printers):
 
 	Printing some PDFs from evince is crashing our Xerox printer
-	http://bugs.freedesktop.org/show_bug.cgi?id=15348
+	https://bugs.freedesktop.org/show_bug.cgi?id=15348
 
 	Cairo-generated postscript blocks Dell 5100cn
-	http://bugs.freedesktop.org/show_bug.cgi?id=15445
+	https://bugs.freedesktop.org/show_bug.cgi?id=15445
 
 Add missing locking in cairo-xlib
 ---------------------------------
@@ -2588,7 +3073,7 @@
 As of cairo 1.6, cairo now depends on the pixman library, for which
 the latest release can be obtained alongside cairo:
 
-	http://cairographics.org/releases/pixman-0.10.0.tar.gz
+	https://cairographics.org/releases/pixman-0.10.0.tar.gz
 
 This library provides all software rendering for cairo, (the
 implementation of the image backend as well as any image fallbacks
@@ -2626,7 +3111,7 @@
 printers). This bug is being tracked here:
 
 	Printing some PDFs from evince is crashing our Xerox printer
-	http://bugs.freedesktop.org/show_bug.cgi?id=15348
+	https://bugs.freedesktop.org/show_bug.cgi?id=15348
 
 New support for arbitrary X server visuals (Thanks, Keith and Behdad!)
 ----------------------------------------------------------------------
@@ -2694,7 +3179,7 @@
 predictable, (previously image rendering and geometry rendering would
 be slightly misaligned with respect to each other).
 
-The reference manual at http://cairographics.org/manual now documents
+The reference manual at https://cairographics.org/manual now documents
 100% of the functions and types in cairo's public API.
 
 API additions
@@ -2931,7 +3416,7 @@
 Cairo now depends on pixman 0.10.0 which was recently released. The
 latest pixman release can always be found alongside cairo releases at:
 
-   http://cairographics.org/releases
+   https://cairographics.org/releases
 
 Increase the precision of color stops for gradients. This fixes a
 regression in gradient rendering that had been present since the
@@ -3041,7 +3526,7 @@
 following usage:
 
 	--enable-atsui		-> --enable-quartz-font
-	CAIRO_HAS_ATSUI_FONT 	-> CAIRO_HAS_QUARTZ_FONT
+	CAIRO_HAS_ATSUI_FONT	-> CAIRO_HAS_QUARTZ_FONT
 	CAIRO_FONT_TYPE_ATSUI	-> CAIRO_FONT_TYPE_QUARTZ
 
 	cairo_atsui_font_face_create_for_atsu_font_id ->
@@ -3093,7 +3578,7 @@
 ---------
 Fix stroke of path with a non-solid-color source pattern:
 
-	http://bugs.freedesktop.org/show_bug.cgi?id=14556
+	https://bugs.freedesktop.org/show_bug.cgi?id=14556
 
 cairo-quartz
 ------------
@@ -3104,7 +3589,7 @@
 
 Correctly handle gradients with non-identity transformations:
 
-	Fixes http://bugs.freedesktop.org/show_bug.cgi?id=14248
+	Fixes https://bugs.freedesktop.org/show_bug.cgi?id=14248
 
 Add native implementation of REPEAT and REFLECT extend modes for
 gradients.
@@ -3231,7 +3716,7 @@
 
 For full documentation, see:
 
-	http://cairographics.org/manual/cairo-Quartz-Surfaces.html#cairo-quartz-image-surface-create
+	https://cairographics.org/manual/cairo-Quartz-Surfaces.html#cairo-quartz-image-surface-create
 
 Several fixes for cairo_mask().
 
@@ -3606,14 +4091,14 @@
 build cairo. The current release is 0.9.6 and can be obtained from
 here:
 
-	http://cairographics.org/releases/pixman-0.9.6.tar.gz
+	https://cairographics.org/releases/pixman-0.9.6.tar.gz
 
  which can be verified with:
 
-	http://cairographics.org/releases/pixman-0.9.6.tar.gz.sha1
+	https://cairographics.org/releases/pixman-0.9.6.tar.gz.sha1
 	66f01a682c64403a3d7a855ba5aa609ed93bcb9e  pixman-0.9.6.tar.gz
 
-	http://cairographics.org/releases/pixman-0.9.6.tar.gz.sha1.asc
+	https://cairographics.org/releases/pixman-0.9.6.tar.gz.sha1.asc
 	(signed by Carl Worth)
 
 Major PDF/PostScript improvements
@@ -3854,8 +4339,8 @@
 it.) This fixes the bug causing OpenOffice.org to crash as described
 here:
 
-        XError on right click menus in OOo.
-        https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=243811
+	XError on right click menus in OOo.
+	https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=243811
 
 Use IncludeInferiors when using xlib surface as a source (Ryan Lortie)
 ----------------------------------------------------------------------
@@ -3919,7 +4404,7 @@
 hit by the gnome-about program which resulted in dozens of duplicated
 bug reports against that program:
 
-	http://bugzilla.gnome.org/show_bug.cgi?id=431990
+	https://bugzilla.gnome.org/show_bug.cgi?id=431990
 
 We were very pleasantly surprised to see this bug get fixed as a
 side-effect of Chris's work. Well done, Chris!
@@ -4035,16 +4520,16 @@
 
     To build, do:
 
-        make malloc-stats.so
+	make malloc-stats.so
 
     inside util/, and to use, run:
 
-        LD_PRELOAD=malloc-stats.so some-program
+	LD_PRELOAD=malloc-stats.so some-program
 
     For binaries managed by libtool, eg, cairo-perf, do:
 
-        ../libtool --mode=execute /bin/true ./cairo-perf
-        LD_PRELOAD="../util/malloc-stats.so" .libs/lt-cairo-perf
+	../libtool --mode=execute /bin/true ./cairo-perf
+	LD_PRELOAD="../util/malloc-stats.so" .libs/lt-cairo-perf
 
 Finally, the cairo-perf-diff-files utility was enhanced to allow for
 generating performance reports from several runs of the same backend
@@ -4116,7 +4601,7 @@
    Johnson)
 
  • Fix glyph positioning bug when glyphs are not horizontal
-	http://lists.freedesktop.org/archives/cairo/2007-April/010337.html
+	https://lists.freedesktop.org/archives/cairo/2007-April/010337.html
 
 win32:
  • Fix crash when rendering with bitmap fonts (Carl Worth)
@@ -4167,7 +4652,7 @@
 • Fix a crash due to a LOCK vs. UNLOCK typo (M. Drochner fixing Carl
   Worth's embarrassing typo).
 
-  http://bugs.freedesktop.org/show_bug.cgi?id=10235
+  https://bugs.freedesktop.org/show_bug.cgi?id=10235
 
 • Fix potential buffer overflow, which on some systems with a checking
   variant of snprintf would lead to a crash (Adrian Johnson, Stanislav
@@ -4212,7 +4697,7 @@
   PDF output in some viewers. (Adrian Johnson, Adam Goode, and
   MenTaLguY).
 
-  http://lists.freedesktop.org/archives/cairo/2006-November/008551.html
+  https://lists.freedesktop.org/archives/cairo/2006-November/008551.html
 
 • win32: Return correct metrics when hinting is off, and fix font
   descent computation (Behdad Esfahbod).
@@ -4929,7 +5414,7 @@
    mentioned here:
 
 	CAIRO_BO_GUARD_BITS and coordinate space?
-	http://lists.freedesktop.org/archives/cairo/2006-December/008743.html
+	https://lists.freedesktop.org/archives/cairo/2006-December/008743.html
 
  * Fix several regressions in new tessellator (M Joonas Pihlaja)
 
@@ -4989,7 +5474,7 @@
    His own writeup of the work he did is quite thorough, but more than
    can be quoted here. Please see his post for the interesting details:
 
-   http://lists.freedesktop.org/archives/cairo/2006-November/008483.html
+   https://lists.freedesktop.org/archives/cairo/2006-November/008483.html
 
    (Though note that this snapshot also includes some additional,
    significant improvements that were only sketched out in that
@@ -5373,54 +5858,54 @@
 Rendering fixes
 ---------------
 Fix image surfaces to not be clipped when used as a source (Vladimir Vukicevic)
-http://gitweb.freedesktop.org/?p=cairo;a=commit;h=72e25648c4c4bc82ddd938aa4e05887a293f0d8b
+https://gitweb.freedesktop.org/?p=cairo;a=commit;h=72e25648c4c4bc82ddd938aa4e05887a293f0d8b
 
 Fix a couple of corner cases in dashing degenerate paths (Jeff Muizelaar)
-http://gitweb.freedesktop.org/?p=cairo;a=commit;h=fbb1758ba8384650157b2bbbc93d161b0c2a05f0
+https://gitweb.freedesktop.org/?p=cairo;a=commit;h=fbb1758ba8384650157b2bbbc93d161b0c2a05f0
 
 Fix support for type1 fonts on win32 (Adrian Johnson)
-http://gitweb.freedesktop.org/?p=cairo;a=commit;h=da1019c9138695cb838a54f8b871bbfd0e8996d7
+https://gitweb.freedesktop.org/?p=cairo;a=commit;h=da1019c9138695cb838a54f8b871bbfd0e8996d7
 
 Fix assertion failure when rotating bitmap fonts (Carl Worth)
-http://gitweb.freedesktop.org/?p=cairo;a=commit;h=0bfa6d4f33b8ddb5dc55bbe419c15df4af856ff9
+https://gitweb.freedesktop.org/?p=cairo;a=commit;h=0bfa6d4f33b8ddb5dc55bbe419c15df4af856ff9
 
 Fix assertion failure when calling cairo_text_path with bitmap fonts (Carl Worth)
-http://gitweb.freedesktop.org/?p=cairo;a=commit;h=9878a033531e6b96b5f27e69e10e90dee7440cd9
+https://gitweb.freedesktop.org/?p=cairo;a=commit;h=9878a033531e6b96b5f27e69e10e90dee7440cd9
 
 Fix mis-handling of cairo_close_path in some situations (Tim Rowley, Carl Worth)
-http://gitweb.freedesktop.org/?p=cairo;a=commit;h=53f74e59faf1af78f2f0741ccf1f23aa5dad4efc
+https://gitweb.freedesktop.org/?p=cairo;a=commit;h=53f74e59faf1af78f2f0741ccf1f23aa5dad4efc
 
 Respect font_matrix translation in _cairo_gstate_glyph_path (Behdad Esfahbod)
-http://gitweb.freedesktop.org/?p=cairo;a=commit;h=f183b835b111d23e838889178aa8106ec84663b3
+https://gitweb.freedesktop.org/?p=cairo;a=commit;h=f183b835b111d23e838889178aa8106ec84663b3
 
 Fix vertical metrics adjustment to work with non-identity shapes (Behdad Esfahbod)
-http://gitweb.freedesktop.org/?p=cairo;a=commit;h=b7bc263842a798d657a95e539e1693372448837f
+https://gitweb.freedesktop.org/?p=cairo;a=commit;h=b7bc263842a798d657a95e539e1693372448837f
 
 [PS] Set correct ImageMatrix in _cairo_ps_surface_emit_bitmap_glyph_data (Behdad Esfahbod)
-http://gitweb.freedesktop.org/?p=cairo;a=commit;h=d47388ad759b0a1a0869655a87d9b5eb6ae2445d
+https://gitweb.freedesktop.org/?p=cairo;a=commit;h=d47388ad759b0a1a0869655a87d9b5eb6ae2445d
 
 Build system fixes
 ------------------
 Fix xlib detection to prefer pkg-config to avoid false libXt dependency (Behdad Esfahbod)
-http://gitweb.freedesktop.org/?p=cairo;a=commit;h=0e78e7144353703cbd28aae6a67cd9ca261f1d68
+https://gitweb.freedesktop.org/?p=cairo;a=commit;h=0e78e7144353703cbd28aae6a67cd9ca261f1d68
 
 Fix typos causing win32 build problem with PS,PDF, and SVG backends (Behdad Esfahbod)
-http://gitweb.freedesktop.org/?p=cairo;a=commit;h=aea83b908d020e26732753830bb3056e6702a774
+https://gitweb.freedesktop.org/?p=cairo;a=commit;h=aea83b908d020e26732753830bb3056e6702a774
 
 Fix configure cache to not use stale results (Behdad Esfahbod)
-http://gitweb.freedesktop.org/?p=cairo;a=commit;h=6d0e3260444a2d5b6fb0cb223ac79f1c0e7b3a6e
+https://gitweb.freedesktop.org/?p=cairo;a=commit;h=6d0e3260444a2d5b6fb0cb223ac79f1c0e7b3a6e
 
 Fix to not pass unsupported warning options to the compiler (Jens Granseuer)
-http://gitweb.freedesktop.org/?p=cairo;a=commit;h=97524a8fdb899de1ae4a3e920fb7bda6d76c5571
+https://gitweb.freedesktop.org/?p=cairo;a=commit;h=97524a8fdb899de1ae4a3e920fb7bda6d76c5571
 
 Fix to allow env. variables such as png_REQUIRES to override configure detection (Jens Granseuer)
-http://gitweb.freedesktop.org/?p=cairo;a=commit;h=abd16e47d6331bd3811c908e524b4dcb6bd23bf0
+https://gitweb.freedesktop.org/?p=cairo;a=commit;h=abd16e47d6331bd3811c908e524b4dcb6bd23bf0
 
 Fix test suite to not use an old system cairo when converting svg2png (Behdad Esfahbod)
-http://gitweb.freedesktop.org/?p=cairo;a=commit;h=6122cc85c8f71b1ba2df3ab86907768edebe1781
+https://gitweb.freedesktop.org/?p=cairo;a=commit;h=6122cc85c8f71b1ba2df3ab86907768edebe1781
 
 Fix test suite to not require signal.h to be present (Behdad Esfahbod)
-http://gitweb.freedesktop.org/?p=cairo;a=commit;h=6f8cf53b1e1ccdbe1ab6a275656b19c6e5120e40
+https://gitweb.freedesktop.org/?p=cairo;a=commit;h=6f8cf53b1e1ccdbe1ab6a275656b19c6e5120e40
 
 Code cleanups
 -------------
@@ -5446,7 +5931,7 @@
 provide a visual with BGR rather than RGB channel order.
 
 report:	https://bugs.freedesktop.org/show_bug.cgi?id=7294
-fix:	http://gitweb.freedesktop.org/?p=cairo;a=commit;h=9ae66174e774b57f16ad791452ed44efc2770a59
+fix:	https://gitweb.freedesktop.org/?p=cairo;a=commit;h=9ae66174e774b57f16ad791452ed44efc2770a59
 
 Fix the "disappearing text" bug
 -------------------------------
@@ -5460,7 +5945,7 @@
 to be disabled more than desired.
 
 report:	https://bugs.freedesktop.org/show_bug.cgi?id=7494
-fix:	http://gitweb.freedesktop.org/?p=cairo;a=commit;h=456cdb3058f3b416109a9600167cd8842300ae14
+fix:	https://gitweb.freedesktop.org/?p=cairo;a=commit;h=456cdb3058f3b416109a9600167cd8842300ae14
 see also:
 Xorg:	https://bugs.freedesktop.org/show_bug.cgi?id=7681
 KDE:	http://qa.mandriva.com/show_bug.cgi?id=23990
@@ -5476,7 +5961,7 @@
 to increasingly shrunken output).
 
 report:	https://bugs.freedesktop.org/show_bug.cgi?id=7533
-fix:	http://gitweb.freedesktop.org/?p=cairo;a=commit;h=1feb4291cf7813494355459bb547eec604c54ffb
+fix:	https://gitweb.freedesktop.org/?p=cairo;a=commit;h=1feb4291cf7813494355459bb547eec604c54ffb
 
 Fix inadvertent semantic change of font matrix translation (Behdad Esfahbod)
 ----------------------------------------------------------------------------
@@ -5490,7 +5975,7 @@
 change. With 1.2.2 we return to the 1.0 semantics, with a much better
 implementation that provides correct glyph metrics.
 
-fix:	http://gitweb.freedesktop.org/?p=cairo;a=commit;h=84840e6bba6e72aa88fad7a0ee929e8955ba9051
+fix:	https://gitweb.freedesktop.org/?p=cairo;a=commit;h=84840e6bba6e72aa88fad7a0ee929e8955ba9051
 
 Fix create_similar to preserve fallback resolution and font options (Behdad Esfahbod)
 -------------------------------------------------------------------------------------
@@ -5502,8 +5987,8 @@
 fallbacks, for example.
 
 report:	https://bugs.freedesktop.org/show_bug.cgi?id=4106
-fixes:	http://gitweb.freedesktop.org/?p=cairo;a=commit;h=9fcb3c32c1f16fe6ab913e27eb54d18b7d9a06b0
-	http://gitweb.freedesktop.org/?p=cairo;a=commit;h=bdb4e1edadb78a2118ff70b28163f8bd4317f1ec
+fixes:	https://gitweb.freedesktop.org/?p=cairo;a=commit;h=9fcb3c32c1f16fe6ab913e27eb54d18b7d9a06b0
+	https://gitweb.freedesktop.org/?p=cairo;a=commit;h=bdb4e1edadb78a2118ff70b28163f8bd4317f1ec
 
 xlib: Fix text performance regression from 1.0 to 1.2.0 (Vladimir Vukicevic)
 ----------------------------------------------------------------------------
@@ -5515,7 +6000,7 @@
 connection). The slowdown was identified and fixed in 1.2.2.
 
 report:	https://bugs.freedesktop.org/show_bug.cgi?id=7514
-fix:	http://gitweb.freedesktop.org/?p=cairo;a=commit;h=b7191885c88068dad57d68ced69a752d1162b12c
+fix:	https://gitweb.freedesktop.org/?p=cairo;a=commit;h=b7191885c88068dad57d68ced69a752d1162b12c
 
 PDF: Eliminate dependency on FreeType library dependency (Adrian Johnson)
 -------------------------------------------------------------------------
@@ -5527,16 +6012,16 @@
 platform.
 
 report:	https://bugs.freedesktop.org/show_bug.cgi?id=7538
-fix:	http://gitweb.freedesktop.org/?p=cairo;a=commit;h=a0989f427be87c60415963dd6822b3c5c3781691
+fix:	https://gitweb.freedesktop.org/?p=cairo;a=commit;h=a0989f427be87c60415963dd6822b3c5c3781691
 
 PDF: Fix broken output on amd64 (Adrian Johnson)
 ------------------------------------------------
-report:	http://bugzilla.gnome.org/show_bug.cgi?id=349826
-fix:	http://gitweb.freedesktop.org/?p=cairo;a=commit;h=f4b12e497b7ac282b2f6831b8fb68deebc412e60
+report:	https://bugzilla.gnome.org/show_bug.cgi?id=349826
+fix:	https://gitweb.freedesktop.org/?p=cairo;a=commit;h=f4b12e497b7ac282b2f6831b8fb68deebc412e60
 
 PS: Fix broken output for truetype fonts > 64k (Adrian Johnson)
 ---------------------------------------------------------------
-fix:	http://gitweb.freedesktop.org/?p=cairo;a=commit;h=067d97eb1793a6b0d0dddfbd0b54117844511a94
+fix:	https://gitweb.freedesktop.org/?p=cairo;a=commit;h=067d97eb1793a6b0d0dddfbd0b54117844511a94
 
 PDF: Fix so that dashing doesn't get stuck on (Kent Worsnop)
 ------------------------------------------------------------
@@ -5544,26 +6029,26 @@
 stroke was performed with dashing, all subsequent strokes would also
 be dashed. There was no way to turn dashing off again.
 
-fix:	http://gitweb.freedesktop.org/?p=cairo;a=commit;h=778c4730a86296bf0a71080cf7008d7291792256
+fix:	https://gitweb.freedesktop.org/?p=cairo;a=commit;h=778c4730a86296bf0a71080cf7008d7291792256
 
 Fix memory leaks in failure paths in gradient creation (Alfred Peng)
 --------------------------------------------------------------------
-fix:	http://gitweb.freedesktop.org/?p=cairo;a=commit;h=db06681b487873788b51a6766894fc619eb8d8f2
+fix:	https://gitweb.freedesktop.org/?p=cairo;a=commit;h=db06681b487873788b51a6766894fc619eb8d8f2
 
 Fix memory leak in _cairo_surface_show_glyphs (Chris Wilson)
 ------------------------------------------------------------
 report:	https://bugs.freedesktop.org/show_bug.cgi?id=7766
-fix:	http://gitweb.freedesktop.org/?p=cairo;a=commit;h=e2fddcccb43d06486d3680a19cfdd5a54963fcbd
+fix:	https://gitweb.freedesktop.org/?p=cairo;a=commit;h=e2fddcccb43d06486d3680a19cfdd5a54963fcbd
 
 Solaris: Add definition of cairo_private for some Sun compilers (Alfred Peng)
 -----------------------------------------------------------------------------
 report:	https://bugzilla.mozilla.org/show_bug.cgi?id=341874
-fix:	http://gitweb.freedesktop.org/?p=cairo;a=commit;h=04757a3aa8deeff3265719ebe01b021638990ec6
+fix:	https://gitweb.freedesktop.org/?p=cairo;a=commit;h=04757a3aa8deeff3265719ebe01b021638990ec6
 
 Solaris: Change version number of Sun's Xorg server with buggy repeat (Brian Cameron)
 -------------------------------------------------------------------------------------
 report: https://bugs.freedesktop.org/show_bug.cgi?id=7483
-fix:	http://gitweb.freedesktop.org/?p=cairo;a=commit;h=e0ad1aa995bcec4246c0b8ab0d5a5a79871ce235
+fix:	https://gitweb.freedesktop.org/?p=cairo;a=commit;h=e0ad1aa995bcec4246c0b8ab0d5a5a79871ce235
 
 Various memory leak fixes
 -------------------------
@@ -5612,7 +6097,7 @@
  * PS/PDF: Fix broken placement for vertical glyphs
  * PS: Fix to not draw BUTT-capped zero-length dash segments
  * Do device offset before float->fixed conversion
-   http://bugzilla.gnome.org/show_bug.cgi?id=332266
+   https://bugzilla.gnome.org/show_bug.cgi?id=332266
  * PS: Fix source surfaces with transformations
  * PS: Fix to not draw BUTT-capped degnerate sub-paths
  * PS: Don't walk off end of array when printing "~>"
@@ -5779,7 +6264,7 @@
 1.2 release of cairo. For a list of items still needing work on the
 cairo 1.2 roadmap, please see:
 
-	http://cairographics.org/ROADMAP
+	https://cairographics.org/ROADMAP
 
 As can be seen in that list, there are no longer any API additions
 left on the roadmap. Instead, there is a feature (PDF type 3 fonts) a
@@ -5874,7 +6359,7 @@
 upcoming 1.2 release of cairo. For a list of items still needing work
 on the cairo 1.2 roadmap, please see:
 
-	http://cairographics.org/ROADMAP
+	https://cairographics.org/ROADMAP
 
 The items included in this snapshot (since the 1.1.2 snapshot) are
 described below.
@@ -5887,9 +6372,9 @@
 specific to the PostScript backend:
 
 	cairo_ps_surface_set_size
-        cairo_ps_surface_dsc_comment
-        cairo_ps_surface_dsc_begin_setup
-        cairo_ps_surface_dsc_begin_page_setup
+	cairo_ps_surface_dsc_comment
+	cairo_ps_surface_dsc_begin_setup
+	cairo_ps_surface_dsc_begin_page_setup
 
 These functions allow variation of the page size/orientation from one
 page to the next in the PostScript output. They also allow the toolkit
@@ -7041,7 +7526,7 @@
 has begun some long-needed work on the documentation, which can now be
 viewed online here:
 
-	http://cairographics.org/manual/
+	https://cairographics.org/manual/
 
 New backend: win32
 ------------------
@@ -7073,7 +7558,7 @@
 
 And see also the documentation at:
 
-http://cairographics.org/manual/cairo-Microsoft-Windows-Backend.html
+https://cairographics.org/manual/cairo-Microsoft-Windows-Backend.html
 
 Disabled backend: quartz
 ------------------------
@@ -7102,7 +7587,7 @@
  Added cairo_font_extents and cairo_font_glyph_extents. See
  documentation for details:
 
- http://cairographics.org/manual/cairo-cairo-t.html#cairo-font-extents
+ https://cairographics.org/manual/cairo-cairo-t.html#cairo-font-extents
 
  cairo-ft.h
  ----------
@@ -7109,7 +7594,7 @@
  The cairo_ft_font API changed considerably. Please see the
  documentation for details:
 
- http://cairographics.org/manual/cairo-FreeType-Fonts.html
+ https://cairographics.org/manual/cairo-FreeType-Fonts.html
 
 Performance
 -----------
@@ -7175,9 +7660,9 @@
 	cc `pkg-config --cflags --libs cairo` -o foo foo.c
 
    IMPORTANT: Users with old versions of cairo installed will need to
-              manually remove cairo.h and cairo-features.h from the
-              system include directories in order to prevent the old
-              headers from being used in preference to the new ones.
+	      manually remove cairo.h and cairo-features.h from the
+	      system include directories in order to prevent the old
+	      headers from being used in preference to the new ones.
 
 2) The backend-specific portions of the old monolithic cairo.h have
    been split out into individual public header files. The new files
@@ -7184,14 +7669,14 @@
    are:
 
 	cairo-atsui.h
-        cairo-ft.h
-        cairo-glitz.h
-        cairo-pdf.h
-        cairo-png.h
-        cairo-ps.h
+	cairo-ft.h
+	cairo-glitz.h
+	cairo-pdf.h
+	cairo-png.h
+	cairo-ps.h
 	cairo-quartz.h
-        cairo-xcb.h
-        cairo-xlib.h
+	cairo-xcb.h
+	cairo-xlib.h
 
    Applications will need to be modified to explicitly include the new
    header files where appropriate.
@@ -7260,7 +7745,7 @@
 the xlib backend. A screenshot of this program running on Mac OS X is
 available here:
 
-	http://cairographics.org/~cworth/images/fdclock-quartz.png
+	https://cairographics.org/~cworth/images/fdclock-quartz.png
 
 ATSUI font backend
 ------------------
@@ -7555,10 +8040,10 @@
 This snapshot provides much better text support by implementing the
 following four functions:
 
-        cairo_text_extents
-        cairo_glyph_extents
-        cairo_text_path
-        cairo_glyph_path
+	cairo_text_extents
+	cairo_glyph_extents
+	cairo_text_path
+	cairo_glyph_path
 
 The text/glyph_extents functions can be used to determine the bounding
 box (and advance) for text as if drawn by show_text/glyphs.

Modified: trunk/Build/source/libs/cairo/cairo-src/README
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/README	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/README	2018-10-20 03:19:36 UTC (rev 48952)
@@ -1,5 +1,5 @@
 Cairo - Multi-platform 2D graphics library
-http://cairographics.org
+https://cairographics.org
 
 What is cairo
 =============
@@ -35,25 +35,25 @@
 =========================================
 The primary source of information about cairo is:
 
-	http://cairographics.org/
+	https://cairographics.org/
 
 The latest versions of cairo can always be found at:
 
-	http://cairographics.org/download
+	https://cairographics.org/download
 
 Documentation on using cairo and frequently-asked questions:
 
-	http://cairographics.org/documentation
-	http://cairographics.org/FAQ
+	https://cairographics.org/documentation
+	https://cairographics.org/FAQ
 
 Mailing lists for contacting cairo users and developers:
 
-	http://cairographics.org/lists
+	https://cairographics.org/lists
 
 Roadmap and unscheduled things to do, (please feel free to help out):
 
-	http://cairographics.org/roadmap
-	http://cairographics.org/todo
+	https://cairographics.org/roadmap
+	https://cairographics.org/todo
 
 Dependencies
 ============
@@ -91,7 +91,7 @@
 ------------------------------------
 	image backend (required)
 	------------------------
-	pixman >= 0.30.0	http://cairographics.org/releases
+	pixman >= 0.30.0	https://cairographics.org/releases
 
 	png support (can be left out if desired, but many
 	-----------  applications expect it to be present)
@@ -113,15 +113,15 @@
 -----------------------------------
 	xlib backend
 	------------
-	X11			http://freedesktop.org/Software/xlibs
+	X11			https://freedesktop.org/Software/xlibs
 
 	xlib-xrender backend
 	--------------------
-	Xrender >= 0.6		http://freedesktop.org/Software/xlibs
+	Xrender >= 0.6		https://freedesktop.org/Software/xlibs
 
 	quartz backend
 	--------------
-	MacOS X >= 10.5 with Xcode >= 3.0
+	MacOS X >= 10.4 with Xcode >= 2.5
 
 	win32 backend
 	-------------
@@ -129,7 +129,7 @@
 
 	xcb backend
 	-----------
-	XCB			http://xcb.freedesktop.org
+	XCB			https://xcb.freedesktop.org
 
 Font backends (required to have at least one)
 ---------------------------------------------
@@ -181,13 +181,7 @@
 	packages and developer dependencies are available at Netlabs:
 				ftp://ftp.netlabs.org/pub/cairo
 
-	skia backend
-	------------
-	Requires the skia library as of June 2014.  Since skia is not
-	API stable, building against newer (or older) versions of skia
-	will probably fail.
 
-
 Compiling
 =========
 See the INSTALL document for build instructions.

Modified: trunk/Build/source/libs/cairo/cairo-src/RELEASING
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/RELEASING	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/RELEASING	2018-10-20 03:19:36 UTC (rev 48952)
@@ -1,5 +1,18 @@
 Here are the steps to follow to create a new cairo release:
 
+0) Decide type of release and checkout the appropriate branch.
+
+	The Cairo project makes three types of releases: Development
+	snapshot releases, stable minor releases, and stable micro (aka
+	"point") releases.  Micro releases should be only bugfixes and
+	no API additions.  If there are API additions consider making a
+	Minor release.  Snapshot releases can be done of the current
+	development tree between Minor releases, as desired.
+
+	For stable releases (both minor and micro), the work should be
+	done on the given release branch.  E.g. for 1.14.12, check out
+	the 1.14 branch via "git checkout origin/1.14 -b 1.14".
+
 1) Ensure that there are no local, uncommitted/unpushed mods.
 
 	You're probably in a good state if both "git diff
@@ -45,12 +58,6 @@
 
 3) Decide what the new version number for the release will be.
 
-	There are three types of releases:  Minor, Micro, and
-	Snapshot.  Micro releases should be only bugfixes and no API
-	additions.  If there are API additions consider making a Minor
-	release.  Snapshot releases can be done of the current
-	development tree between Minor releases, as desired.
-
 	Cairo uses even numbers for official releases, and odd numbers
 	for development snapshots.  Thus, for a Minor release it would
 	be:
@@ -76,8 +83,6 @@
 		LAST_RELEASE="X.Y.Z"     # e.g. 1.15.2
 		THIS_RELEASE="X.Y.Z+2"   # e.g. 1.15.4
 
-
-
 4) Fill out an entry in the NEWS file
 
 	Sift through the logs since the last release. This is most
@@ -99,7 +104,7 @@
 	Include a link to the incremental ChangeLog for this release,
 	which we'll be uploading in a later step:
 
-		http://cairographics.org/releases/ChangeLog.cairo-${THIS_RELEASE}
+		https://cairographics.org/releases/ChangeLog.cairo-${THIS_RELEASE}
 
 4) Increment cairo_version_{minor|micro} in cairo-version.h:
 
@@ -117,12 +122,21 @@
 	Otherwise, (i.e. there are only bug fixes), increment
 	cairo_version_micro to the next larger (even) number.
 
-5) Commit the changes to NEWS and cairo-version.h
+5) For Minor releases, add an index entry to doc/public/cairo-docs.xml
 
+        Towards the end of the file, add a new section for the stable
+	release.  It'll look something like:
+
+	<index id="index-X.Y" role="X.Y">
+	  <title>Index of new symbols in X.Y</title>
+	</index>
+
+6) Commit the changes to NEWS and cairo-version.h
+
 	It's especially important to mention the new version number in your
 	commit log.
 
-6) Run "make release-publish" which will perform the following steps
+7) Run "make release-publish" which will perform the following steps
    for you:
 
 	* Generate ChangeLog files out of git repository
@@ -133,10 +147,10 @@
 	* Generate the final tar file
 	* Generate an sha1sum file
 	* Sign the sha1sum using your GPG setup (asks for your GPG password)
-	* scp the three files to appear on http://cairographics.org/releases
+	* scp the three files to appear on https://cairographics.org/releases
 	* Generate a versioned manual and upload it to appear as both:
-	  http://cairographics.org/manual-${THIS_RELEASE}
-	  http://cairographics.org/manual
+	  https://cairographics.org/manual-${THIS_RELEASE}
+	  https://cairographics.org/manual
 	* Place local copies of the three files in the releases directory
 	* Create a LATEST-package-version file (after deleting any old one)
 	* Tag the entire source tree with a ${THIS_RELEASE} tag, and sign
@@ -159,26 +173,33 @@
 	previous versions, remove manual-${THIS_RELEASE} and
 	release/cairo-${THIS_RELEASE}.
 
-7) Update trunk (or the stable branch) version number.
+8) Push the new tag out to the central tree with a command like:
 
-	For Micro releases (X.Y.Z), increment cairo_version_micro to the
-	next larger (odd) number in cairo-version.h, commit, and push.
+	git push origin master ${THIS_RELEASE}
 
+9) Update master (or the stable branch) version number.
+
+	For Micro releases (X.Y.Z+2), increment cairo_version_micro to
+	the next larger (odd) number in cairo-version.h, commit, and
+	push.
+
+		DEVEL_VERSION="X.Y.Z+1"  # e.g. 1.15.10 -> 1.15.11
+
 	For Minor releases (X.Y.0), increment cairo_version_minor to the
 	next larger (odd) number, and set cairo_version_micro to 1.  Then
 	commit and push.
 
-8) Push the new tag out to the central tree with a command like:
+	       DEVEL_VERSION="X.Y.Z+1"  # e.g. 1.16.0 -> 1.17.1
 
-	git push origin master ${THIS_RELEASE}
+	git commit cairo-version.h -m "Bump version for ${DEVEL_VERSION}"
 
-9) Edit the cairo bugzilla product and add the new version numbers.
+10) Edit the cairo bugzilla product and add the new version numbers.
 
 	Note that you need to add two versions.  One for the
 	release/snapshot (with an even micro version), another with the
 	post-release version (with an odd micro version).
 
-10) Send out an announcement message.
+11) Send out an announcement message.
 
 	Send a message to cairo-announce at cairographics.org and CC
 	cairo at cairographics.org, gnome-announce-list at gnome.org and
@@ -189,5 +210,8 @@
 
 		git shortlog ${LAST_RELEASE}...
 
-11) Add the announcement to the NEWS page and the front page.
+12) Add the announcement to the website as a new entry in the news/
+    dir.  It will automatically get indexed onto the homepage when the
+    site refreshes.
 
+

Modified: trunk/Build/source/libs/cairo/cairo-src/build/Makefile.am.gtk-doc
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/build/Makefile.am.gtk-doc	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/build/Makefile.am.gtk-doc	2018-10-20 03:19:36 UTC (rev 48952)
@@ -8,7 +8,7 @@
 #   - Some other changed introduced in 7f114b781f5c530d57530e5f76402e41cdabac6b
 #
 # Before changing it, check to see if a newer gtk-doc.make has fixed the issue you are facing.
-# From time to time, it would be nice to udpate this to the latest copy of gtk-doc.make, but
+# From time to time, it would be nice to update this to the latest copy of gtk-doc.make, but
 # please do review all the differences and port our modifications forward.
 #
 
@@ -42,8 +42,8 @@
 	$(DOC_MODULE)-sections.txt	\
 	$(DOC_MODULE)-overrides.txt
 
-DOC_STAMPS=scan-build.stamp tmpl-build.stamp sgml-build.stamp html-build.stamp \
-	   $(srcdir)/tmpl.stamp $(srcdir)/sgml.stamp $(srcdir)/html.stamp
+DOC_STAMPS=scan-build.stamp sgml-build.stamp html-build.stamp \
+	   $(srcdir)/sgml.stamp $(srcdir)/html.stamp
 
 SCANOBJ_FILES = 		 \
 	$(DOC_MODULE).args 	 \
@@ -88,26 +88,11 @@
 $(DOC_MODULE)-decl.txt $(SCANOBJ_FILES) $(DOC_MODULE)-sections.txt $(DOC_MODULE)-overrides.txt: scan-build.stamp
 	@true
 
-#### templates ####
-
-tmpl-build.stamp: $(DOC_MODULE)-decl.txt $(SCANOBJ_FILES) $(DOC_MODULE)-sections.txt $(DOC_MODULE)-overrides.txt
-	@echo 'gtk-doc: Rebuilding template files'
-	@-chmod -R u+w $(srcdir)
-	cd $(srcdir) && gtkdoc-mktmpl --module=$(DOC_MODULE) $(MKTMPL_OPTIONS)
-	touch tmpl-build.stamp
-
-tmpl.stamp: tmpl-build.stamp
-	@true
-
-tmpl/*.sgml:
-	@true
-
-
 #### xml ####
 
 # gtkdoc-mkdb is broken and requires a --root-dir=$(srcdir) option
 # The _srcdir diversion is fragile but works for make check; make distcheck
-sgml-build.stamp: tmpl.stamp $(HFILE_GLOB) $(CFILE_GLOB) $(DOC_MODULE)-sections.txt $(srcdir)/tmpl/*.sgml $(expand_content_files)
+sgml-build.stamp: $(HFILE_GLOB) $(CFILE_GLOB) $(DOC_MODULE)-sections.txt $(expand_content_files)
 	@echo 'gtk-doc: Building XML'
 	@-chmod -R u+w $(srcdir)
 	_srcdir="`pwd`/$(DOC_SOURCE_DIR)"; \
@@ -127,7 +112,7 @@
 	cd $(srcdir)/html && gtkdoc-mkhtml $(DOC_MODULE) ../$(DOC_MAIN_SGML_FILE)
 	test "x$(HTML_IMAGES)" = "x" || ( cd $(srcdir) && cp $(HTML_IMAGES) html )
 	@echo 'gtk-doc: Fixing cross-references'
-	cd $(srcdir) && gtkdoc-fixxref --module-dir=html --html-dir=$(HTML_DIR) $(FIXXREF_OPTIONS)
+	cd $(srcdir) && gtkdoc-fixxref --module=$(DOC_MODULE) --module-dir=html --html-dir=$(HTML_DIR) $(FIXXREF_OPTIONS)
 	touch html-build.stamp
 
 ##############
@@ -176,10 +161,8 @@
 endif
 
 dist-hook: dist-check-gtkdoc dist-hook-local
-	mkdir $(distdir)/tmpl
 	mkdir $(distdir)/xml
 	mkdir $(distdir)/html
-	-cp $(srcdir)/tmpl/*.sgml $(distdir)/tmpl
 	-cp $(srcdir)/xml/*.xml $(distdir)/xml
 	cp $(srcdir)/html/* $(distdir)/html
 	-cp $(srcdir)/$(DOC_MODULE).types $(distdir)/

Modified: trunk/Build/source/libs/cairo/cairo-src/build/Makefile.am.releasing
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/build/Makefile.am.releasing	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/build/Makefile.am.releasing	2018-10-20 03:19:36 UTC (rev 48952)
@@ -31,7 +31,7 @@
 RELEASE_UPLOAD_HOST =   cairographics.org
 RELEASE_UPLOAD_BASE =	/srv/cairo.freedesktop.org/www
 RELEASE_UPLOAD_DIR =	$(RELEASE_UPLOAD_BASE)/$(RELEASE_OR_SNAPSHOT)s
-RELEASE_URL_BASE = 	http://cairographics.org/$(RELEASE_OR_SNAPSHOT)s
+RELEASE_URL_BASE = 	https://cairographics.org/$(RELEASE_OR_SNAPSHOT)s
 RELEASE_ANNOUNCE_LIST = cairo-announce at cairographics.org (and CC gnome-announce-list at gnome.org)
 
 MANUAL_VERSIONED =		manual-$(VERSION)

Modified: trunk/Build/source/libs/cairo/cairo-src/build/Makefile.win32.features
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/build/Makefile.win32.features	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/build/Makefile.win32.features	2018-10-20 03:19:36 UTC (rev 48952)
@@ -11,7 +11,6 @@
 CAIRO_HAS_QUARTZ_IMAGE_SURFACE=0
 CAIRO_HAS_WIN32_SURFACE=1
 CAIRO_HAS_WIN32_FONT=1
-CAIRO_HAS_SKIA_SURFACE=0
 CAIRO_HAS_OS2_SURFACE=0
 CAIRO_HAS_BEOS_SURFACE=0
 CAIRO_HAS_DRM_SURFACE=0
@@ -19,6 +18,7 @@
 CAIRO_HAS_PNG_FUNCTIONS=1
 CAIRO_HAS_GL_SURFACE=0
 CAIRO_HAS_GLESV2_SURFACE=0
+CAIRO_HAS_GLESV3_SURFACE=0
 CAIRO_HAS_COGL_SURFACE=0
 CAIRO_HAS_DIRECTFB_SURFACE=0
 CAIRO_HAS_VG_SURFACE=0

Modified: trunk/Build/source/libs/cairo/cairo-src/build/Makefile.win32.features-h
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/build/Makefile.win32.features-h	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/build/Makefile.win32.features-h	2018-10-20 03:19:36 UTC (rev 48952)
@@ -38,9 +38,6 @@
 ifeq ($(CAIRO_HAS_WIN32_FONT),1)
 	@echo "#define CAIRO_HAS_WIN32_FONT 1" >> $(top_srcdir)/src/cairo-features.h
 endif
-ifeq ($(CAIRO_HAS_SKIA_SURFACE),1)
-	@echo "#define CAIRO_HAS_SKIA_SURFACE 1" >> $(top_srcdir)/src/cairo-features.h
-endif
 ifeq ($(CAIRO_HAS_OS2_SURFACE),1)
 	@echo "#define CAIRO_HAS_OS2_SURFACE 1" >> $(top_srcdir)/src/cairo-features.h
 endif
@@ -62,6 +59,9 @@
 ifeq ($(CAIRO_HAS_GLESV2_SURFACE),1)
 	@echo "#define CAIRO_HAS_GLESV2_SURFACE 1" >> $(top_srcdir)/src/cairo-features.h
 endif
+ifeq ($(CAIRO_HAS_GLESV3_SURFACE),1)
+	@echo "#define CAIRO_HAS_GLESV3_SURFACE 1" >> $(top_srcdir)/src/cairo-features.h
+endif
 ifeq ($(CAIRO_HAS_COGL_SURFACE),1)
 	@echo "#define CAIRO_HAS_COGL_SURFACE 1" >> $(top_srcdir)/src/cairo-features.h
 endif

Modified: trunk/Build/source/libs/cairo/cairo-src/build/aclocal.cairo.m4
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/build/aclocal.cairo.m4	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/build/aclocal.cairo.m4	2018-10-20 03:19:36 UTC (rev 48952)
@@ -165,7 +165,7 @@
 int atomic_add(int i) { return __sync_fetch_and_add (&i, 1); }
 int atomic_cmpxchg(int i, int j, int k) { return __sync_val_compare_and_swap (&i, j, k); }
 ], [],
-		  cairo_cv_atomic_primitives="Intel"
+		  cairo_cv_atomic_primitives="gcc-legacy"
 		  )
 
 		AC_TRY_LINK([
@@ -190,9 +190,9 @@
 			  [Enable if your compiler supports the GCC __atomic_* atomic primitives])
 	fi
 
-	if test "x$cairo_cv_atomic_primitives" = xIntel; then
-		AC_DEFINE(HAVE_INTEL_ATOMIC_PRIMITIVES, 1,
-			  [Enable if your compiler supports the Intel __sync_* atomic primitives])
+	if test "x$cairo_cv_atomic_primitives" = xgcc-legacy; then
+		AC_DEFINE(HAVE_GCC_LEGACY_ATOMICS, 1,
+			  [Enable if your compiler supports the legacy GCC __sync_* atomic primitives])
 	fi
 
 	if test "x$cairo_cv_atomic_primitives" = "xlibatomic-ops"; then
@@ -215,7 +215,7 @@
 		case $host_cpu in
 		    i?86)	cairo_cv_atomic_op_needs_memory_barrier="no"  ;;
 		    x86_64)	cairo_cv_atomic_op_needs_memory_barrier="no"  ;;
-		    arm*)	cairo_cv_atomic_op_needs_memory_barrier="no"  ;;
+		    arm*)	cairo_cv_atomic_op_needs_memory_barrier="yes"  ;;
 		    *)		cairo_cv_atomic_op_needs_memory_barrier="yes" ;;
 		esac
 	])

Modified: trunk/Build/source/libs/cairo/cairo-src/build/aclocal.float.m4
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/build/aclocal.float.m4	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/build/aclocal.float.m4	2018-10-20 03:19:36 UTC (rev 48952)
@@ -12,7 +12,7 @@
   [AC_CACHE_CHECK(whether float word ordering is bigendian,
                   ax_cv_c_float_words_bigendian, [
 
-# The endianess is detected by first compiling C code that contains a special
+# The endianness is detected by first compiling C code that contains a special
 # double float value, then grepping the resulting object file for certain
 # strings of ascii values. The double is specially crafted to have a
 # binary representation that corresponds with a simple string. In this

Modified: trunk/Build/source/libs/cairo/cairo-src/build/aclocal.pkg.m4
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/build/aclocal.pkg.m4	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/build/aclocal.pkg.m4	2018-10-20 03:19:36 UTC (rev 48952)
@@ -146,7 +146,7 @@
 
 _PKG_TEXT
 
-To get pkg-config, see <http://pkg-config.freedesktop.org/>.])],
+To get pkg-config, see <https://pkg-config.freedesktop.org/>.])],
 		[$4])
 else
 	$1[]_CFLAGS=$pkg_cv_[]$1[]_CFLAGS

Modified: trunk/Build/source/libs/cairo/cairo-src/build/configure.ac.features
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/build/configure.ac.features	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/build/configure.ac.features	2018-10-20 03:19:36 UTC (rev 48952)
@@ -369,7 +369,7 @@
 	echo "  Mime:          yes (always builtin)"
 	echo "  Tee:           $use_tee"
 	echo "  XML:           $use_xml"
-	echo "  Skia:          $use_skia"
+	#echo "  Skia:          $use_skia"
 	echo "  Xlib:          $use_xlib"
 	echo "  Xlib Xrender:  $use_xlib_xrender"
 	echo "  Qt:            $use_qt"
@@ -384,6 +384,7 @@
 	echo "  SVG:           $use_svg"
 	echo "  OpenGL:        $use_gl"
 	echo "  OpenGL ES 2.0: $use_glesv2"
+	echo "  OpenGL ES 3.0: $use_glesv3"
 	echo "  BeOS:          $use_beos"
 	echo "  DirectFB:      $use_directfb"
 	echo "  OpenVG:        $use_vg"

Modified: trunk/Build/source/libs/cairo/cairo-src/build/configure.ac.system
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/build/configure.ac.system	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/build/configure.ac.system	2018-10-20 03:19:36 UTC (rev 48952)
@@ -108,7 +108,7 @@
 
 dnl check for misc headers and functions
 AC_CHECK_HEADERS([libgen.h byteswap.h signal.h setjmp.h fenv.h sys/wait.h])
-AC_CHECK_FUNCS([ctime_r drand48 flockfile funlockfile getline link strndup])
+AC_CHECK_FUNCS([ctime_r localtime_r gmtime_r drand48 flockfile funlockfile getline link strndup])
 
 dnl Check if the runtime platform is a native Win32 host.
 AC_COMPILE_IFELSE([[

Modified: trunk/Build/source/libs/cairo/cairo-src/build/configure.ac.tools
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/build/configure.ac.tools	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/build/configure.ac.tools	2018-10-20 03:19:36 UTC (rev 48952)
@@ -12,7 +12,7 @@
 
 PKG_PROG_PKG_CONFIG()
 if test "x$PKG_CONFIG" = x; then
-	AC_MSG_ERROR([pkg-config >= $PKGCONFIG_REQUIRED required but not found (http://pkgconfig.freedesktop.org/)])
+	AC_MSG_ERROR([pkg-config >= $PKGCONFIG_REQUIRED required but not found (https://pkgconfig.freedesktop.org/)])
 fi
 
 dnl Check for recent pkg-config which supports Requires.private

Modified: trunk/Build/source/libs/cairo/cairo-src/build/gtk-doc.m4
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/build/gtk-doc.m4	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/build/gtk-doc.m4	2018-10-20 03:19:36 UTC (rev 48952)
@@ -1,4 +1,29 @@
-dnl -*- mode: autoconf -*-
+# -*- mode: autoconf -*-
+#
+# gtk-doc.m4 - configure macro to check for gtk-doc
+# Copyright (C) 2003 James Henstridge
+#               2007-2017  Stefan Sauer
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+# As a special exception, the above copyright owner gives unlimited
+# permission to copy, distribute and modify the configure scripts that
+# are the output of Autoconf when processing the Macro. You need not
+# follow the terms of the GNU General Public License when using or
+# distributing such scripts, even though portions of the text of the
+# Macro appear in them. The GNU General Public License (GPL) does govern
+# all other use of the material that constitutes the Autoconf Macro.
 
 # serial 2
 

Modified: trunk/Build/source/libs/cairo/cairo-src/cairo-version.h
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/cairo-version.h	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/cairo-version.h	2018-10-20 03:19:36 UTC (rev 48952)
@@ -2,7 +2,7 @@
 #define CAIRO_VERSION_H
 
 #define CAIRO_VERSION_MAJOR 1
-#define CAIRO_VERSION_MINOR 14
-#define CAIRO_VERSION_MICRO 12
+#define CAIRO_VERSION_MINOR 16
+#define CAIRO_VERSION_MICRO 0
 
 #endif

Modified: trunk/Build/source/libs/cairo/cairo-src/config.h.in
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/config.h.in	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/config.h.in	2018-10-20 03:19:36 UTC (rev 48952)
@@ -52,6 +52,9 @@
    significant word first */
 #undef FLOAT_WORDS_BIGENDIAN
 
+/* Define to (0) if freetype2 does not support color fonts */
+#undef FT_HAS_COLOR
+
 /* Enable pixman glyph cache */
 #undef HAS_PIXMAN_GLYPHS
 
@@ -110,6 +113,12 @@
 /* Define to 1 if you have the `fork' function. */
 #undef HAVE_FORK
 
+/* Define to 1 if you have the `FT_Done_MM_Var' function. */
+#undef HAVE_FT_DONE_MM_VAR
+
+/* Define to 1 if you have the `FT_Get_Var_Design_Coordinates' function. */
+#undef HAVE_FT_GET_VAR_DESIGN_COORDINATES
+
 /* Define to 1 if you have the `FT_Get_X11_Font_Format' function. */
 #undef HAVE_FT_GET_X11_FONT_FORMAT
 
@@ -128,6 +137,10 @@
 /* Define to 1 if you have the `funlockfile' function. */
 #undef HAVE_FUNLOCKFILE
 
+/* Enable if your compiler supports the legacy GCC __sync_* atomic primitives
+   */
+#undef HAVE_GCC_LEGACY_ATOMICS
+
 /* Whether you have gcov */
 #undef HAVE_GCOV
 
@@ -134,8 +147,8 @@
 /* Define to 1 if you have the `getline' function. */
 #undef HAVE_GETLINE
 
-/* Enable if your compiler supports the Intel __sync_* atomic primitives */
-#undef HAVE_INTEL_ATOMIC_PRIMITIVES
+/* Define to 1 if you have the `gmtime_r' function. */
+#undef HAVE_GMTIME_R
 
 /* Define to 1 if you have the <inttypes.h> header file. */
 #undef HAVE_INTTYPES_H
@@ -155,6 +168,9 @@
 /* Define to 1 if you have the `link' function. */
 #undef HAVE_LINK
 
+/* Define to 1 if you have the `localtime_r' function. */
+#undef HAVE_LOCALTIME_R
+
 /* Define to 1 if you have the Valgrind lockdep tool */
 #undef HAVE_LOCKDEP
 
@@ -174,6 +190,9 @@
 /* Define to 1 if you have the `mmap' function. */
 #undef HAVE_MMAP
 
+/* Define to 1 if you have the `newlocale' function. */
+#undef HAVE_NEWLOCALE
+
 /* Enable if you have MacOS X atomic operations */
 #undef HAVE_OS_ATOMIC_OPS
 
@@ -213,6 +232,9 @@
 /* Define to 1 if you have the `strndup' function. */
 #undef HAVE_STRNDUP
 
+/* Define to 1 if you have the `strtod_l' function. */
+#undef HAVE_STRTOD_L
+
 /* Define to 1 if you have the <sys/int_types.h> header file. */
 #undef HAVE_SYS_INT_TYPES_H
 
@@ -243,6 +265,9 @@
 /* Define to 1 if you have the <time.h> header file. */
 #undef HAVE_TIME_H
 
+/* Define to 1 if typeof works with your compiler. */
+#undef HAVE_TYPEOF
+
 /* Define to 1 if the system has the type `uint128_t'. */
 #undef HAVE_UINT128_T
 
@@ -267,6 +292,9 @@
 /* Define to 1 if you have the <X11/extensions/XShm.h> header file. */
 #undef HAVE_X11_EXTENSIONS_XSHM_H
 
+/* Define to 1 if you have the <xlocale.h> header file. */
+#undef HAVE_XLOCALE_H
+
 /* Define to 1 if you have the `XRenderCreateConicalGradient' function. */
 #undef HAVE_XRENDERCREATECONICALGRADIENT
 
@@ -410,3 +438,6 @@
 #ifndef __cplusplus
 #undef inline
 #endif
+
+/* Define to __typeof__ if your compiler spells it that way. */
+#undef typeof

Modified: trunk/Build/source/libs/cairo/cairo-src/configure.ac
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/configure.ac	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/configure.ac	2018-10-20 03:19:36 UTC (rev 48952)
@@ -2,9 +2,9 @@
 CAIRO_PARSE_VERSION
 AC_INIT([cairo],
 	[cairo_version_major.cairo_version_minor.cairo_version_micro],
-	[http://bugs.freedesktop.org/enter_bug.cgi?product=cairo],
+	[https://bugs.freedesktop.org/enter_bug.cgi?product=cairo],
 	[cairo],
-	[http://cairographics.org/])
+	[https://cairographics.org/])
 AC_CONFIG_AUX_DIR(build)
 AC_CONFIG_MACRO_DIR(build)
 AC_USE_SYSTEM_EXTENSIONS
@@ -12,6 +12,7 @@
 AC_CONFIG_HEADERS(config.h)
 
 AC_CHECK_HEADERS([unistd.h sys/ioctl.h])
+AC_C_TYPEOF
 
 AM_INIT_AUTOMAKE([1.11 foreign -Wall no-define no-dist-gzip dist-xz])
 AM_SILENT_RULES([yes])
@@ -75,6 +76,9 @@
 fi
 AM_CONDITIONAL(CAIRO_HAS_DLSYM, test "x$have_dlsym" = "xyes")
 
+AC_CHECK_HEADERS(xlocale.h)
+AC_CHECK_FUNCS(newlocale strtod_l)
+
 dnl ===========================================================================
 
 CAIRO_ENABLE_SURFACE_BACKEND(xlib, Xlib, auto, [
@@ -139,7 +143,7 @@
 		       CPPFLAGS="$CPPFLAGS $xlib_CFLAGS $xlib_NONPKGCONFIG_CFLAGS"
 		       AC_CHECK_HEADER(X11/extensions/Xrender.h,
 				       [xlib_xrender_NONPKGCONFIG_LIBS="-lXrender"],
-				       [use_xlib_xrender="no (requires $xlib_xrender_REQUIRES http://freedesktop.org/Software/xlibs)"],
+				       [use_xlib_xrender="no (requires $xlib_xrender_REQUIRES https://freedesktop.org/Software/xlibs)"],
 				       [#include <X11/X.h>])
 		       CPPFLAGS=$old_CPPFLAGS
 		      ])
@@ -160,7 +164,7 @@
 CAIRO_ENABLE_SURFACE_BACKEND(xcb, XCB, auto, [
   xcb_REQUIRES="xcb >= 1.6 xcb-render >= 1.6"
   PKG_CHECK_MODULES(xcb, $xcb_REQUIRES, ,
-		    [use_xcb="no (requires $xcb_REQUIRES http://xcb.freedesktop.org)"])
+		    [use_xcb="no (requires $xcb_REQUIRES https://xcb.freedesktop.org)"])
 ])
 
 CAIRO_ENABLE_FUNCTIONS(xlib_xcb, Xlib/XCB, no, [
@@ -167,7 +171,7 @@
   if test "x$use_xcb" = "xyes" -a "x$use_xlib" = "xyes"; then
     xlib_xcb_REQUIRES="x11-xcb"
     PKG_CHECK_MODULES(xlib_xcb, $xlib_xcb_REQUIRES, ,
-		      [use_xlib_xcb="no (requires $xlib_xcb_REQUIRES http://xcb.freedesktop.org)"])
+		      [use_xlib_xcb="no (requires $xlib_xcb_REQUIRES https://xcb.freedesktop.org)"])
   else
     use_xlib_xcb="no (requires both --enable-xlib and --enable-xcb)"
   fi
@@ -177,7 +181,7 @@
   if test "x$use_xcb" = "xyes"; then
       xcb_shm_REQUIRES="xcb-shm"
       PKG_CHECK_MODULES(xcb_shm, $xcb_shm_REQUIRES, ,
-			[use_xcb_shm="no (requires $xcb_shm http://xcb.freedesktop.org)"])
+			[use_xcb_shm="no (requires $xcb_shm https://xcb.freedesktop.org)"])
   else
     use_xcb_shm="no (requires --enable-xcb)"
   fi
@@ -245,27 +249,6 @@
 
 dnl ===========================================================================
 
-CAIRO_ENABLE_SURFACE_BACKEND(skia, Skia, no, [
-  AC_ARG_WITH([skia],
-	      [AS_HELP_STRING([--with-skia=/path/to/skia],
-			      [directory to find compiled skia sources])],
-	      [skia_DIR="$withval"],
-	      [skia_DIR="`pwd`/../skia"])
-  AC_ARG_WITH([skia-build-type],
-	      [AS_HELP_STRING([--with-skia-build-type=(Release|Debug)]
-			      [build of skia to link with, default is Release])],
-	      [skia_BUILD_TYPE="$withval"],
-	      [skia_BUILD_TYPE="Release"])
-  skia_NONPKGCONFIG_CFLAGS="-I$skia_DIR/include/config -I$skia_DIR/include/core -I$skia_DIR/include/effects"
-  if test "x$skia_BUILD_TYPE" = "xRelease"; then
-  	skia_NONPKGCONFIG_CFLAGS="-DSK_RELEASE -DSK_CAN_USE_FLOAT $skia_NONPKGCONFIG_CFLAGS"
-  fi
-  skia_NONPKGCONFIG_LIBS="-L$skia_DIR/out/$skia_BUILD_TYPE/lib.target/ -lskia -lstdc++"
-  AC_SUBST(skia_DIR)
-])
-
-dnl ===========================================================================
-
 CAIRO_ENABLE_SURFACE_BACKEND(os2, OS/2, no, [
   case "$host" in
     *-*-os2*)
@@ -296,7 +279,7 @@
 dnl ===========================================================================
 
 CAIRO_ENABLE_SURFACE_BACKEND(drm, DRM, no, [
-  drm_REQUIRES="libudev >= 136"
+  drm_REQUIRES="libudev >= 136, libdrm >= 2.4"
   PKG_CHECK_MODULES(drm, $drm_REQUIRES, ,
    [use_drm="no (requires $drm_REQUIRES, udev is available from git://git.kernel.org/pub/scm/linux/hotplug/udev.git)"])
 ])
@@ -386,6 +369,32 @@
 ])
 
 dnl ===========================================================================
+CAIRO_ENABLE_SURFACE_BACKEND(glesv3, OpenGLESv3, no, [
+  dnl glesv3 is provided via libGLESv2.so, so require glesv2.pc (there is no libGLESv3, nor glesv3.pc)
+  glesv3_REQUIRES="glesv2"
+  PKG_CHECK_MODULES(glesv3, $glesv3_REQUIRES,, [
+    use_glesv3="no (glesv2.pc not found, required for glesv3)"
+  ])
+
+  dnl Since there is no glesv3.pc, need to search for header files
+  AC_CHECK_HEADER(GLES3/gl3.h,, [use_glesv3="no (OpenGL ES 3.0 headers not found)"])
+  if test "x$use_glesv3" = "xyes"; then
+    glesv3_NONPKGCONFIG_CFLAGS=
+    glesv3_NONPKGCONFIG_LIBS="-lGLESv2"
+  fi
+
+  if test "x$have_dl" = "xyes" -a "x$have_dlsym" = "xyes"; then
+    glesv3_LIBS="$glesv3_LIBS -ldl"
+  fi
+
+  if test "x$use_glesv3" = "xyes" -a "x$use_gl" = "xyes"; then
+      AC_MSG_ERROR([use either --enable-gl=yes or --enable-glesv3=yes. Not both at the same time.])
+  fi
+
+  need_egl_functions=yes
+])
+
+dnl ===========================================================================
 CAIRO_ENABLE_SURFACE_BACKEND(cogl, Cogl, no, [
   cogl_REQUIRES="cogl-2.0-experimental"
   PKG_CHECK_MODULES(cogl, $cogl_REQUIRES,, [use_cogl="no"])
@@ -470,6 +479,9 @@
 any2ppm_cs=no
 CAIRO_ENABLE_SURFACE_BACKEND(script, script, yes, [
   any2ppm_cs=yes
+  # The script backend requires zlib.
+  use_script=$have_libz
+  script_NONPKGCONFIG_LIBS=-lz
 ])
 
 dnl ===========================================================================
@@ -544,8 +556,19 @@
   LIBS="$LIBS $ft_LIBS"
   CFLAGS="$CFLAGS $ft_CFLAGS"
 
-  AC_CHECK_FUNCS(FT_Get_X11_Font_Format FT_GlyphSlot_Embolden FT_GlyphSlot_Oblique FT_Load_Sfnt_Table FT_Library_SetLcdFilter)
+  AC_CHECK_FUNCS(FT_Get_X11_Font_Format FT_GlyphSlot_Embolden FT_GlyphSlot_Oblique FT_Load_Sfnt_Table FT_Library_SetLcdFilter FT_Get_Var_Design_Coordinates FT_Done_MM_Var)
 
+  AC_MSG_CHECKING(for FT_HAS_COLOR)
+  AC_LINK_IFELSE([AC_LANG_PROGRAM([
+#include <ft2build.h>
+#include FT_FREETYPE_H
+],[
+FT_Long has_color = FT_HAS_COLOR( ((FT_Face)NULL) );
+])],[AC_MSG_RESULT([yes])],[
+  AC_DEFINE([FT_HAS_COLOR(x)], [(0)], [Define to (0) if freetype2 does not support color fonts])
+  AC_MSG_RESULT([no, disable color font (freetype2 >= 2.5.1 is required)])
+])
+
   LIBS="$_save_libs"
   CFLAGS="$_save_cflags"
 fi
@@ -664,7 +687,7 @@
 CAIRO_ENABLE_SURFACE_BACKEND(image, image, always, [
   pixman_REQUIRES="pixman-1 >= 0.30.0"
   PKG_CHECK_MODULES(pixman, $pixman_REQUIRES, ,
-    [use_image="no (requires $pixman_REQUIRES http://cairographics.org/releases/)"])
+    [use_image="no (requires $pixman_REQUIRES https://cairographics.org/releases/)"])
   image_REQUIRES=$pixman_REQUIRES
   image_CFLAGS=$pixman_CFLAGS
   image_LIBS=$pixman_LIBS
@@ -712,7 +735,7 @@
 CAIRO_ENABLE_FUNCTIONS(gobject, gobject, auto, [
   gobject_REQUIRES="gobject-2.0 glib-2.0 >= 2.14"
   PKG_CHECK_MODULES(GOBJECT, $gobject_REQUIRES, ,
-    [use_gobject="no (requires $gobject_REQUIRES http://download.gnome.org/pub/GNOME/sources/glib/)"])
+    [use_gobject="no (requires $gobject_REQUIRES https://download.gnome.org/pub/GNOME/sources/glib/)"])
   gobject_NONPKGCONFIG_EXTRA_LIBS="-L\${libdir} -lcairo-gobject"
 ])
 dnl I'm too lazy to fix the caching properly
@@ -839,7 +862,6 @@
 
 dnl Extra stuff we need to do when building C++ code
 need_cxx="no"
-AS_IF([test "x$use_skia" = "xyes"], [need_cxx="yes"])
 AS_IF([test "x$use_qt" = "xyes"], [need_cxx="yes"])
 AS_IF([test "x$use_beos" = "xyes"], [need_cxx="yes"])
 

Modified: trunk/Build/source/libs/cairo/cairo-src/src/Makefile.am.features
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/src/Makefile.am.features	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/src/Makefile.am.features	2018-10-20 03:19:36 UTC (rev 48952)
@@ -193,22 +193,6 @@
 enabled_cairo_pkgconf += cairo-win32-font.pc
 endif
 
-unsupported_cairo_headers += $(cairo_skia_headers)
-all_cairo_headers += $(cairo_skia_headers)
-all_cairo_private += $(cairo_skia_private)
-all_cairo_cxx_sources += $(cairo_skia_cxx_sources)
-all_cairo_sources += $(cairo_skia_sources)
-if CAIRO_HAS_SKIA_SURFACE
-enabled_cairo_headers += $(cairo_skia_headers)
-enabled_cairo_private += $(cairo_skia_private)
-enabled_cairo_cxx_sources += $(cairo_skia_cxx_sources)
-enabled_cairo_sources += $(cairo_skia_sources)
-endif
-all_cairo_pkgconf += cairo-skia.pc
-if CAIRO_HAS_SKIA_SURFACE
-enabled_cairo_pkgconf += cairo-skia.pc
-endif
-
 unsupported_cairo_headers += $(cairo_os2_headers)
 all_cairo_headers += $(cairo_os2_headers)
 all_cairo_private += $(cairo_os2_private)
@@ -321,6 +305,22 @@
 enabled_cairo_pkgconf += cairo-glesv2.pc
 endif
 
+unsupported_cairo_headers += $(cairo_glesv3_headers)
+all_cairo_headers += $(cairo_glesv3_headers)
+all_cairo_private += $(cairo_glesv3_private)
+all_cairo_cxx_sources += $(cairo_glesv3_cxx_sources)
+all_cairo_sources += $(cairo_glesv3_sources)
+if CAIRO_HAS_GLESV3_SURFACE
+enabled_cairo_headers += $(cairo_glesv3_headers)
+enabled_cairo_private += $(cairo_glesv3_private)
+enabled_cairo_cxx_sources += $(cairo_glesv3_cxx_sources)
+enabled_cairo_sources += $(cairo_glesv3_sources)
+endif
+all_cairo_pkgconf += cairo-glesv3.pc
+if CAIRO_HAS_GLESV3_SURFACE
+enabled_cairo_pkgconf += cairo-glesv3.pc
+endif
+
 unsupported_cairo_headers += $(cairo_cogl_headers)
 all_cairo_headers += $(cairo_cogl_headers)
 all_cairo_private += $(cairo_cogl_private)

Modified: trunk/Build/source/libs/cairo/cairo-src/src/Makefile.sources
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/src/Makefile.sources	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/src/Makefile.sources	2018-10-20 03:19:36 UTC (rev 48952)
@@ -64,10 +64,10 @@
 	cairo-clip-private.h \
 	cairo-combsort-inline.h \
 	cairo-compiler-private.h \
+	cairo-composite-rectangles-private.h \
 	cairo-compositor-private.h \
 	cairo-contour-inline.h \
 	cairo-contour-private.h \
-	cairo-composite-rectangles-private.h \
 	cairo-damage-private.h \
 	cairo-default-context-private.h \
 	cairo-device-private.h \
@@ -75,10 +75,10 @@
 	cairo-error-private.h \
 	cairo-fixed-private.h \
 	cairo-fixed-type-private.h \
+	cairo-fontconfig-private.h \
+	cairo-freed-pool-private.h \
 	cairo-freelist-private.h \
 	cairo-freelist-type-private.h \
-	cairo-freed-pool-private.h \
-	cairo-fontconfig-private.h \
 	cairo-gstate-private.h \
 	cairo-hash-private.h \
 	cairo-image-info-private.h \
@@ -110,26 +110,26 @@
 	cairo-rtree-private.h \
 	cairo-scaled-font-private.h \
 	cairo-slope-private.h \
+	cairo-spans-compositor-private.h \
 	cairo-spans-private.h \
-	cairo-spans-compositor-private.h \
 	cairo-stroke-dash-private.h \
-	cairo-surface-inline.h \
-	cairo-surface-private.h \
 	cairo-surface-backend-private.h \
 	cairo-surface-clipper-private.h \
 	cairo-surface-fallback-private.h \
+	cairo-surface-inline.h \
 	cairo-surface-observer-inline.h \
 	cairo-surface-observer-private.h \
 	cairo-surface-offset-private.h \
+	cairo-surface-private.h \
+	cairo-surface-snapshot-inline.h \
+	cairo-surface-snapshot-private.h \
 	cairo-surface-subsurface-inline.h \
 	cairo-surface-subsurface-private.h \
-	cairo-surface-snapshot-inline.h \
-	cairo-surface-snapshot-private.h \
 	cairo-surface-wrapper-private.h \
 	cairo-time-private.h \
-	cairo-types-private.h \
 	cairo-traps-private.h \
 	cairo-tristrip-private.h \
+	cairo-types-private.h \
 	cairo-user-font-private.h \
 	cairo-wideint-private.h \
 	cairo-wideint-type-private.h \
@@ -141,19 +141,19 @@
 	cairo-atomic.c \
 	cairo-base64-stream.c \
 	cairo-base85-stream.c \
-	cairo-bentley-ottmann.c \
 	cairo-bentley-ottmann-rectangular.c \
 	cairo-bentley-ottmann-rectilinear.c \
+	cairo-bentley-ottmann.c \
 	cairo-botor-scan-converter.c \
+	cairo-boxes-intersect.c \
 	cairo-boxes.c \
-	cairo-boxes-intersect.c \
-	cairo.c \
 	cairo-cache.c \
-	cairo-clip.c \
 	cairo-clip-boxes.c \
 	cairo-clip-polygon.c \
 	cairo-clip-region.c \
 	cairo-clip-surface.c \
+	cairo-clip-tor-scan-converter.c \
+	cairo-clip.c \
 	cairo-color.c \
 	cairo-composite-rectangles.c \
 	cairo-compositor.c \
@@ -165,12 +165,12 @@
 	cairo-error.c \
 	cairo-fallback-compositor.c \
 	cairo-fixed.c \
+	cairo-font-face-twin-data.c \
+	cairo-font-face-twin.c \
 	cairo-font-face.c \
-	cairo-font-face-twin.c \
-	cairo-font-face-twin-data.c \
 	cairo-font-options.c \
+	cairo-freed-pool.c \
 	cairo-freelist.c \
-	cairo-freed-pool.c \
 	cairo-gstate.c \
 	cairo-hash.c \
 	cairo-hull.c \
@@ -180,10 +180,10 @@
 	cairo-image-surface.c \
 	cairo-line.c \
 	cairo-lzw.c \
+	cairo-mask-compositor.c \
 	cairo-matrix.c \
-	cairo-mask-compositor.c \
+	cairo-mempool.c \
 	cairo-mesh-pattern-rasterizer.c \
-	cairo-mempool.c \
 	cairo-misc.c \
 	cairo-mono-scan-converter.c \
 	cairo-mutex.c \
@@ -192,20 +192,20 @@
 	cairo-output-stream.c \
 	cairo-paginated-surface.c \
 	cairo-path-bounds.c \
-	cairo-path.c \
 	cairo-path-fill.c \
 	cairo-path-fixed.c \
 	cairo-path-in-fill.c \
-	cairo-path-stroke.c \
 	cairo-path-stroke-boxes.c \
 	cairo-path-stroke-polygon.c \
 	cairo-path-stroke-traps.c \
 	cairo-path-stroke-tristrip.c \
+	cairo-path-stroke.c \
+	cairo-path.c \
 	cairo-pattern.c \
 	cairo-pen.c \
-	cairo-polygon.c \
 	cairo-polygon-intersect.c \
 	cairo-polygon-reduce.c \
+	cairo-polygon.c \
 	cairo-raster-source-pattern.c \
 	cairo-recording-surface.c \
 	cairo-rectangle.c \
@@ -215,12 +215,11 @@
 	cairo-scaled-font.c \
 	cairo-shape-mask-compositor.c \
 	cairo-slope.c \
+	cairo-spans-compositor.c \
 	cairo-spans.c \
-	cairo-spans-compositor.c \
 	cairo-spline.c \
 	cairo-stroke-dash.c \
 	cairo-stroke-style.c \
-	cairo-surface.c \
 	cairo-surface-clipper.c \
 	cairo-surface-fallback.c \
 	cairo-surface-observer.c \
@@ -228,18 +227,19 @@
 	cairo-surface-snapshot.c \
 	cairo-surface-subsurface.c \
 	cairo-surface-wrapper.c \
+	cairo-surface.c \
 	cairo-time.c \
 	cairo-tor-scan-converter.c \
 	cairo-tor22-scan-converter.c \
-	cairo-clip-tor-scan-converter.c \
 	cairo-toy-font-face.c \
+	cairo-traps-compositor.c \
 	cairo-traps.c \
 	cairo-tristrip.c \
-	cairo-traps-compositor.c \
 	cairo-unicode.c \
 	cairo-user-font.c \
 	cairo-version.c \
 	cairo-wideint.c \
+	cairo.c \
 	$(NULL)
 
 _cairo_font_subset_private = \
@@ -264,8 +264,16 @@
 cairo_glx_sources =
 cairo_wgl_sources =
 
-_cairo_pdf_operators_private = cairo-pdf-operators-private.h cairo-pdf-shading-private.h
-_cairo_pdf_operators_sources = cairo-pdf-operators.c cairo-pdf-shading.c
+_cairo_pdf_operators_private = \
+	cairo-pdf-operators-private.h \
+	cairo-pdf-shading-private.h \
+	cairo-tag-attributes-private.h \
+	$(NULL)
+_cairo_pdf_operators_sources = \
+	cairo-pdf-operators.c \
+	cairo-pdf-shading.c \
+	cairo-tag-attributes.c \
+	$(NULL)
 cairo_private += $(_cairo_pdf_operators_private)
 cairo_sources += $(_cairo_pdf_operators_sources)
 
@@ -279,8 +287,8 @@
 cairo_sources += $(_cairo_deflate_stream_sources)
 
 cairo_pdf_headers = cairo-pdf.h
-cairo_pdf_private = cairo-pdf-surface-private.h
-cairo_pdf_sources = cairo-pdf-surface.c
+cairo_pdf_private = cairo-pdf-surface-private.h cairo-tag-stack-private.h
+cairo_pdf_sources = cairo-pdf-surface.c cairo-pdf-interchange.c cairo-tag-stack.c
 
 cairo_svg_headers = cairo-svg.h
 cairo_svg_private = cairo-svg-surface-private.h
@@ -367,13 +375,6 @@
 	win32/cairo-win32-font.c \
 	$(NULL)
 
-cairo_skia_headers = cairo-skia.h
-cairo_skia_private = skia/cairo-skia-private.h
-cairo_skia_cxx_sources = \
-	skia/cairo-skia-context.cpp \
-	skia/cairo-skia-surface.cpp \
-	$(NULL)
-
 cairo_os2_headers = cairo-os2.h
 cairo_os2_private = cairo-os2-private.h
 cairo_os2_sources = cairo-os2-surface.c
@@ -395,18 +396,22 @@
 		   cairo-gl-glyphs.c \
 		   cairo-gl-gradient.c \
 		   cairo-gl-info.c \
+		   cairo-gl-msaa-compositor.c \
 		   cairo-gl-operand.c \
 		   cairo-gl-shaders.c \
-		   cairo-gl-msaa-compositor.c \
+		   cairo-gl-source.c \
 		   cairo-gl-spans-compositor.c \
-		   cairo-gl-traps-compositor.c \
-		   cairo-gl-source.c \
-		   cairo-gl-surface.c
+		   cairo-gl-surface.c \
+		   cairo-gl-traps-compositor.c
 
 cairo_glesv2_headers = $(cairo_gl_headers)
 cairo_glesv2_private = $(cairo_gl_private)
 cairo_glesv2_sources = $(cairo_gl_sources)
 
+cairo_glesv3_headers = $(cairo_gl_headers)
+cairo_glesv3_private = $(cairo_gl_private)
+cairo_glesv3_sources = $(cairo_gl_sources)
+
 cairo_egl_sources += cairo-egl-context.c
 cairo_glx_sources += cairo-glx-context.c
 cairo_wgl_sources += cairo-wgl-context.c
@@ -416,7 +421,6 @@
 
 cairo_drm_headers = cairo-drm.h
 cairo_drm_private = drm/cairo-drm-private.h \
-		    drm/cairo-drm-ioctl-private.h \
 		    drm/cairo-drm-intel-private.h \
 		    drm/cairo-drm-intel-brw-defines.h \
 		    drm/cairo-drm-intel-brw-structs.h \

Modified: trunk/Build/source/libs/cairo/cairo-src/src/Makefile.win32.features
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/src/Makefile.win32.features	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/src/Makefile.win32.features	2018-10-20 03:19:36 UTC (rev 48952)
@@ -197,22 +197,6 @@
 enabled_cairo_pkgconf += cairo-win32-font.pc
 endif
 
-unsupported_cairo_headers += $(cairo_skia_headers)
-all_cairo_headers += $(cairo_skia_headers)
-all_cairo_private += $(cairo_skia_private)
-all_cairo_cxx_sources += $(cairo_skia_cxx_sources)
-all_cairo_sources += $(cairo_skia_sources)
-ifeq ($(CAIRO_HAS_SKIA_SURFACE),1)
-enabled_cairo_headers += $(cairo_skia_headers)
-enabled_cairo_private += $(cairo_skia_private)
-enabled_cairo_cxx_sources += $(cairo_skia_cxx_sources)
-enabled_cairo_sources += $(cairo_skia_sources)
-endif
-all_cairo_pkgconf += cairo-skia.pc
-ifeq ($(CAIRO_HAS_SKIA_SURFACE),1)
-enabled_cairo_pkgconf += cairo-skia.pc
-endif
-
 unsupported_cairo_headers += $(cairo_os2_headers)
 all_cairo_headers += $(cairo_os2_headers)
 all_cairo_private += $(cairo_os2_private)
@@ -325,6 +309,22 @@
 enabled_cairo_pkgconf += cairo-glesv2.pc
 endif
 
+unsupported_cairo_headers += $(cairo_glesv3_headers)
+all_cairo_headers += $(cairo_glesv3_headers)
+all_cairo_private += $(cairo_glesv3_private)
+all_cairo_cxx_sources += $(cairo_glesv3_cxx_sources)
+all_cairo_sources += $(cairo_glesv3_sources)
+ifeq ($(CAIRO_HAS_GLESV3_SURFACE),1)
+enabled_cairo_headers += $(cairo_glesv3_headers)
+enabled_cairo_private += $(cairo_glesv3_private)
+enabled_cairo_cxx_sources += $(cairo_glesv3_cxx_sources)
+enabled_cairo_sources += $(cairo_glesv3_sources)
+endif
+all_cairo_pkgconf += cairo-glesv3.pc
+ifeq ($(CAIRO_HAS_GLESV3_SURFACE),1)
+enabled_cairo_pkgconf += cairo-glesv3.pc
+endif
+
 unsupported_cairo_headers += $(cairo_cogl_headers)
 all_cairo_headers += $(cairo_cogl_headers)
 all_cairo_private += $(cairo_cogl_private)

Modified: trunk/Build/source/libs/cairo/cairo-src/src/cairo-analysis-surface.c
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/src/cairo-analysis-surface.c	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/src/cairo-analysis-surface.c	2018-10-20 03:19:36 UTC (rev 48952)
@@ -118,11 +118,11 @@
 {
     struct proxy *proxy;
 
-    proxy = malloc (sizeof (*proxy));
+    proxy = _cairo_malloc (sizeof (*proxy));
     if (unlikely (proxy == NULL))
 	return _cairo_surface_create_in_error (CAIRO_STATUS_NO_MEMORY);
 
-    _cairo_surface_init (&proxy->base, &proxy_backend, NULL, target->content);
+    _cairo_surface_init (&proxy->base, &proxy_backend, NULL, target->content, target->is_vector);
 
     proxy->target = target;
     _cairo_surface_attach_snapshot (source, &proxy->base, NULL);
@@ -138,53 +138,6 @@
 }
 
 static cairo_int_status_t
-_analyze_recording_surface_pattern (cairo_analysis_surface_t *surface,
-				    const cairo_pattern_t    *pattern)
-{
-    const cairo_surface_pattern_t *surface_pattern;
-    cairo_analysis_surface_t *tmp;
-    cairo_surface_t *source, *proxy;
-    cairo_matrix_t p2d;
-    cairo_status_t status, analysis_status;
-
-    assert (pattern->type == CAIRO_PATTERN_TYPE_SURFACE);
-    surface_pattern = (const cairo_surface_pattern_t *) pattern;
-    assert (surface_pattern->surface->type == CAIRO_SURFACE_TYPE_RECORDING);
-    source = surface_pattern->surface;
-
-    proxy = _cairo_surface_has_snapshot (source, &proxy_backend);
-    if (proxy != NULL) {
-	/* nothing untoward found so far */
-	return CAIRO_STATUS_SUCCESS;
-    }
-
-    tmp = (cairo_analysis_surface_t *)
-	_cairo_analysis_surface_create (surface->target);
-    if (unlikely (tmp->base.status))
-	return tmp->base.status;
-    proxy = attach_proxy (source, &tmp->base);
-
-    p2d = pattern->matrix;
-    status = cairo_matrix_invert (&p2d);
-    assert (status == CAIRO_STATUS_SUCCESS);
-
-    cairo_matrix_multiply (&tmp->ctm, &p2d, &surface->ctm);
-    tmp->has_ctm = ! _cairo_matrix_is_identity (&tmp->ctm);
-
-    source = _cairo_surface_get_source (source, NULL);
-    status = _cairo_recording_surface_replay_and_create_regions (source,
-								 &tmp->base);
-    analysis_status = tmp->has_unsupported ? CAIRO_INT_STATUS_IMAGE_FALLBACK : CAIRO_INT_STATUS_SUCCESS;
-    detach_proxy (proxy);
-    cairo_surface_destroy (&tmp->base);
-
-    if (unlikely (status))
-	return status;
-
-    return analysis_status;
-}
-
-static cairo_int_status_t
 _add_operation (cairo_analysis_surface_t *surface,
 		cairo_rectangle_int_t    *rect,
 		cairo_int_status_t        backend_status)
@@ -301,6 +254,104 @@
 	return status;
 }
 
+static cairo_int_status_t
+_analyze_recording_surface_pattern (cairo_analysis_surface_t *surface,
+				    const cairo_pattern_t    *pattern,
+				    cairo_rectangle_int_t    *extents)
+{
+    const cairo_surface_pattern_t *surface_pattern;
+    cairo_analysis_surface_t *tmp;
+    cairo_surface_t *source, *proxy;
+    cairo_matrix_t p2d;
+    cairo_int_status_t status;
+    cairo_int_status_t analysis_status = CAIRO_INT_STATUS_SUCCESS;
+    cairo_bool_t surface_is_unbounded;
+    cairo_bool_t unused;
+
+    assert (pattern->type == CAIRO_PATTERN_TYPE_SURFACE);
+    surface_pattern = (const cairo_surface_pattern_t *) pattern;
+    assert (surface_pattern->surface->type == CAIRO_SURFACE_TYPE_RECORDING);
+    source = surface_pattern->surface;
+
+    proxy = _cairo_surface_has_snapshot (source, &proxy_backend);
+    if (proxy != NULL) {
+	/* nothing untoward found so far */
+	return CAIRO_STATUS_SUCCESS;
+    }
+
+    tmp = (cairo_analysis_surface_t *)
+	_cairo_analysis_surface_create (surface->target);
+    if (unlikely (tmp->base.status)) {
+	status =tmp->base.status;
+	goto cleanup1;
+    }
+    proxy = attach_proxy (source, &tmp->base);
+
+    p2d = pattern->matrix;
+    status = cairo_matrix_invert (&p2d);
+    assert (status == CAIRO_INT_STATUS_SUCCESS);
+    _cairo_analysis_surface_set_ctm (&tmp->base, &p2d);
+
+
+    source = _cairo_surface_get_source (source, NULL);
+    surface_is_unbounded = (pattern->extend == CAIRO_EXTEND_REPEAT
+				     || pattern->extend == CAIRO_EXTEND_REFLECT);
+    status = _cairo_recording_surface_replay_and_create_regions (source,
+								 &pattern->matrix,
+								 &tmp->base,
+								 surface_is_unbounded);
+    if (unlikely (status))
+	goto cleanup2;
+
+    /* black background or mime data fills entire extents */
+    if (!(source->content & CAIRO_CONTENT_ALPHA) || _cairo_surface_has_mime_image (source)) {
+	cairo_rectangle_int_t rect;
+
+	if (_cairo_surface_get_extents (source, &rect)) {
+	    cairo_box_t bbox;
+
+	    _cairo_box_from_rectangle (&bbox, &rect);
+	    _cairo_matrix_transform_bounding_box_fixed (&p2d, &bbox, NULL);
+	    _cairo_box_round_to_rectangle (&bbox, &rect);
+	    status = _add_operation (tmp, &rect, CAIRO_INT_STATUS_SUCCESS);
+	    if (status == CAIRO_INT_STATUS_IMAGE_FALLBACK)
+		status = CAIRO_INT_STATUS_SUCCESS;
+	    if (unlikely (status))
+		goto cleanup2;
+	}
+    }
+
+    if (tmp->has_supported) {
+	surface->has_supported = TRUE;
+	unused = cairo_region_union (&surface->supported_region, &tmp->supported_region);
+    }
+
+    if (tmp->has_unsupported) {
+	surface->has_unsupported = TRUE;
+	unused = cairo_region_union (&surface->fallback_region, &tmp->fallback_region);
+    }
+
+    analysis_status = tmp->has_unsupported ? CAIRO_INT_STATUS_IMAGE_FALLBACK : CAIRO_INT_STATUS_SUCCESS;
+    if (pattern->extend != CAIRO_EXTEND_NONE) {
+	_cairo_unbounded_rectangle_init (extents);
+    } else {
+	status = cairo_matrix_invert (&tmp->ctm);
+	_cairo_matrix_transform_bounding_box_fixed (&tmp->ctm,
+						    &tmp->page_bbox, NULL);
+	_cairo_box_round_to_rectangle (&tmp->page_bbox, extents);
+    }
+
+  cleanup2:
+    detach_proxy (proxy);
+  cleanup1:
+    cairo_surface_destroy (&tmp->base);
+
+    if (unlikely (status))
+	return status;
+    else
+	return analysis_status;
+}
+
 static cairo_status_t
 _cairo_analysis_surface_finish (void *abstract_surface)
 {
@@ -344,7 +395,7 @@
     if (_cairo_operator_bounded_by_source (op)) {
 	cairo_rectangle_int_t source_extents;
 
-	_cairo_pattern_get_extents (source, &source_extents);
+	_cairo_pattern_get_extents (source, &source_extents, surface->target->is_vector);
 	_cairo_rectangle_intersect (extents, &source_extents);
     }
 
@@ -355,7 +406,7 @@
 _cairo_analysis_surface_paint (void			*abstract_surface,
 			       cairo_operator_t		op,
 			       const cairo_pattern_t	*source,
-			       const cairo_clip_t		*clip)
+			       const cairo_clip_t	*clip)
 {
     cairo_analysis_surface_t *surface = abstract_surface;
     cairo_int_status_t	     backend_status;
@@ -371,12 +422,14 @@
 	    return backend_status;
     }
 
-    if (backend_status == CAIRO_INT_STATUS_ANALYZE_RECORDING_SURFACE_PATTERN)
-	backend_status = _analyze_recording_surface_pattern (surface, source);
-
     _cairo_analysis_surface_operation_extents (surface,
 					       op, source, clip,
 					       &extents);
+    if (backend_status == CAIRO_INT_STATUS_ANALYZE_RECORDING_SURFACE_PATTERN) {
+	cairo_rectangle_int_t rec_extents;
+	backend_status = _analyze_recording_surface_pattern (surface, source, &rec_extents);
+	_cairo_rectangle_intersect (&extents, &rec_extents);
+    }
 
     return _add_operation (surface, &extents, backend_status);
 }
@@ -386,7 +439,7 @@
 			      cairo_operator_t		 op,
 			      const cairo_pattern_t	*source,
 			      const cairo_pattern_t	*mask,
-			      const cairo_clip_t		*clip)
+			      const cairo_clip_t	*clip)
 {
     cairo_analysis_surface_t *surface = abstract_surface;
     cairo_int_status_t	      backend_status;
@@ -402,9 +455,13 @@
 	    return backend_status;
     }
 
+    _cairo_analysis_surface_operation_extents (surface,
+					       op, source, clip,
+					       &extents);
     if (backend_status == CAIRO_INT_STATUS_ANALYZE_RECORDING_SURFACE_PATTERN) {
 	cairo_int_status_t backend_source_status = CAIRO_STATUS_SUCCESS;
 	cairo_int_status_t backend_mask_status = CAIRO_STATUS_SUCCESS;
+	cairo_rectangle_int_t rec_extents;
 
 	if (source->type == CAIRO_PATTERN_TYPE_SURFACE) {
 	    cairo_surface_t *src_surface = ((cairo_surface_pattern_t *)source)->surface;
@@ -411,9 +468,11 @@
 	    src_surface = _cairo_surface_get_source (src_surface, NULL);
 	    if (_cairo_surface_is_recording (src_surface)) {
 		backend_source_status =
-		    _analyze_recording_surface_pattern (surface, source);
+		    _analyze_recording_surface_pattern (surface, source, &rec_extents);
 		if (_cairo_int_status_is_error (backend_source_status))
 		    return backend_source_status;
+
+		_cairo_rectangle_intersect (&extents, &rec_extents);
 	    }
 	}
 
@@ -422,9 +481,11 @@
 	    mask_surface = _cairo_surface_get_source (mask_surface, NULL);
 	    if (_cairo_surface_is_recording (mask_surface)) {
 		backend_mask_status =
-		    _analyze_recording_surface_pattern (surface, mask);
+		    _analyze_recording_surface_pattern (surface, mask, &rec_extents);
 		if (_cairo_int_status_is_error (backend_mask_status))
 		    return backend_mask_status;
+
+		_cairo_rectangle_intersect (&extents, &rec_extents);
 	    }
 	}
 
@@ -433,14 +494,10 @@
 						  backend_mask_status);
     }
 
-    _cairo_analysis_surface_operation_extents (surface,
-					       op, source, clip,
-					       &extents);
-
     if (_cairo_operator_bounded_by_mask (op)) {
 	cairo_rectangle_int_t mask_extents;
 
-	_cairo_pattern_get_extents (mask, &mask_extents);
+	_cairo_pattern_get_extents (mask, &mask_extents, surface->target->is_vector);
 	_cairo_rectangle_intersect (&extents, &mask_extents);
     }
 
@@ -448,16 +505,16 @@
 }
 
 static cairo_int_status_t
-_cairo_analysis_surface_stroke (void			*abstract_surface,
-				cairo_operator_t	 op,
-				const cairo_pattern_t	*source,
-				const cairo_path_fixed_t	*path,
-				const cairo_stroke_style_t	*style,
-				const cairo_matrix_t		*ctm,
-				const cairo_matrix_t		*ctm_inverse,
-				double			 tolerance,
-				cairo_antialias_t	 antialias,
-				const cairo_clip_t		*clip)
+_cairo_analysis_surface_stroke (void			   *abstract_surface,
+				cairo_operator_t	    op,
+				const cairo_pattern_t	   *source,
+				const cairo_path_fixed_t   *path,
+				const cairo_stroke_style_t *style,
+				const cairo_matrix_t	   *ctm,
+				const cairo_matrix_t	   *ctm_inverse,
+				double			    tolerance,
+				cairo_antialias_t	    antialias,
+				const cairo_clip_t	   *clip)
 {
     cairo_analysis_surface_t *surface = abstract_surface;
     cairo_int_status_t	     backend_status;
@@ -476,12 +533,14 @@
 	    return backend_status;
     }
 
-    if (backend_status == CAIRO_INT_STATUS_ANALYZE_RECORDING_SURFACE_PATTERN)
-	backend_status = _analyze_recording_surface_pattern (surface, source);
-
     _cairo_analysis_surface_operation_extents (surface,
 					       op, source, clip,
 					       &extents);
+    if (backend_status == CAIRO_INT_STATUS_ANALYZE_RECORDING_SURFACE_PATTERN) {
+	cairo_rectangle_int_t rec_extents;
+	backend_status = _analyze_recording_surface_pattern (surface, source, &rec_extents);
+	_cairo_rectangle_intersect (&extents, &rec_extents);
+    }
 
     if (_cairo_operator_bounded_by_mask (op)) {
 	cairo_rectangle_int_t mask_extents;
@@ -508,7 +567,7 @@
 			      cairo_fill_rule_t		 fill_rule,
 			      double			 tolerance,
 			      cairo_antialias_t		 antialias,
-			      const cairo_clip_t		*clip)
+			      const cairo_clip_t	*clip)
 {
     cairo_analysis_surface_t *surface = abstract_surface;
     cairo_int_status_t	     backend_status;
@@ -526,12 +585,14 @@
 	    return backend_status;
     }
 
-    if (backend_status == CAIRO_INT_STATUS_ANALYZE_RECORDING_SURFACE_PATTERN)
-	backend_status = _analyze_recording_surface_pattern (surface, source);
-
     _cairo_analysis_surface_operation_extents (surface,
 					       op, source, clip,
 					       &extents);
+    if (backend_status == CAIRO_INT_STATUS_ANALYZE_RECORDING_SURFACE_PATTERN) {
+	cairo_rectangle_int_t rec_extents;
+	backend_status = _analyze_recording_surface_pattern (surface, source, &rec_extents);
+	_cairo_rectangle_intersect (&extents, &rec_extents);
+    }
 
     if (_cairo_operator_bounded_by_mask (op)) {
 	cairo_rectangle_int_t mask_extents;
@@ -588,12 +649,14 @@
 	backend_status = CAIRO_INT_STATUS_UNSUPPORTED;
     }
 
-    if (backend_status == CAIRO_INT_STATUS_ANALYZE_RECORDING_SURFACE_PATTERN)
-	backend_status = _analyze_recording_surface_pattern (surface, source);
-
     _cairo_analysis_surface_operation_extents (surface,
 					       op, source, clip,
 					       &extents);
+    if (backend_status == CAIRO_INT_STATUS_ANALYZE_RECORDING_SURFACE_PATTERN) {
+	cairo_rectangle_int_t rec_extents;
+	backend_status = _analyze_recording_surface_pattern (surface, source, &rec_extents);
+	_cairo_rectangle_intersect (&extents, &rec_extents);
+    }
 
     if (_cairo_operator_bounded_by_mask (op)) {
 	status = _cairo_scaled_font_glyph_device_extents (scaled_font,
@@ -664,12 +727,14 @@
 	    return backend_status;
     }
 
-    if (backend_status == CAIRO_INT_STATUS_ANALYZE_RECORDING_SURFACE_PATTERN)
-	backend_status = _analyze_recording_surface_pattern (surface, source);
-
     _cairo_analysis_surface_operation_extents (surface,
 					       op, source, clip,
 					       &extents);
+    if (backend_status == CAIRO_INT_STATUS_ANALYZE_RECORDING_SURFACE_PATTERN) {
+	cairo_rectangle_int_t rec_extents;
+	backend_status = _analyze_recording_surface_pattern (surface, source, &rec_extents);
+	_cairo_rectangle_intersect (&extents, &rec_extents);
+    }
 
     if (_cairo_operator_bounded_by_mask (op)) {
 	status = _cairo_scaled_font_glyph_device_extents (scaled_font,
@@ -686,6 +751,39 @@
     return _add_operation (surface, &extents, backend_status);
 }
 
+static cairo_int_status_t
+_cairo_analysis_surface_tag (void	                *abstract_surface,
+			     cairo_bool_t                begin,
+			     const char                 *tag_name,
+			     const char                 *attributes,
+			     const cairo_pattern_t	*source,
+			     const cairo_stroke_style_t	*stroke_style,
+			     const cairo_matrix_t	*ctm,
+			     const cairo_matrix_t	*ctm_inverse,
+			     const cairo_clip_t	        *clip)
+{
+    cairo_analysis_surface_t *surface = abstract_surface;
+    cairo_int_status_t	     backend_status;
+
+    backend_status = CAIRO_INT_STATUS_SUCCESS;
+    if (surface->target->backend->tag != NULL) {
+	backend_status =
+	    surface->target->backend->tag (surface->target,
+					   begin,
+					   tag_name,
+					   attributes,
+					   source,
+					   stroke_style,
+					   ctm,
+					   ctm_inverse,
+					   clip);
+	if (_cairo_int_status_is_error (backend_status))
+	    return backend_status;
+    }
+
+    return backend_status;
+}
+
 static const cairo_surface_backend_t cairo_analysis_surface_backend = {
     CAIRO_INTERNAL_SURFACE_TYPE_ANALYSIS,
 
@@ -718,7 +816,9 @@
     NULL, /* fill_stroke */
     _cairo_analysis_surface_show_glyphs,
     _cairo_analysis_surface_has_show_text_glyphs,
-    _cairo_analysis_surface_show_text_glyphs
+    _cairo_analysis_surface_show_text_glyphs,
+    NULL, /* get_supported_mime_types */
+    _cairo_analysis_surface_tag
 };
 
 cairo_surface_t *
@@ -731,7 +831,7 @@
     if (unlikely (status))
 	return _cairo_surface_create_in_error (status);
 
-    surface = malloc (sizeof (cairo_analysis_surface_t));
+    surface = _cairo_malloc (sizeof (cairo_analysis_surface_t));
     if (unlikely (surface == NULL))
 	return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
 
@@ -740,7 +840,8 @@
     _cairo_surface_init (&surface->base,
 			 &cairo_analysis_surface_backend,
 			 NULL, /* device */
-			 CAIRO_CONTENT_COLOR_ALPHA);
+			 CAIRO_CONTENT_COLOR_ALPHA,
+			 target->is_vector);
 
     cairo_matrix_init_identity (&surface->ctm);
     surface->has_ctm = FALSE;
@@ -920,7 +1021,7 @@
 {
     cairo_surface_t *surface;
 
-    surface = malloc (sizeof (cairo_surface_t));
+    surface = _cairo_malloc (sizeof (cairo_surface_t));
     if (unlikely (surface == NULL)) {
 	return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
     }
@@ -928,7 +1029,8 @@
     _cairo_surface_init (surface,
 			 &cairo_null_surface_backend,
 			 NULL, /* device */
-			 content);
+			 content,
+			 TRUE); /* is_vector */
 
     return surface;
 }

Modified: trunk/Build/source/libs/cairo/cairo-src/src/cairo-atomic-private.h
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/src/cairo-atomic-private.h	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/src/cairo-atomic-private.h	2018-10-20 03:19:36 UTC (rev 48952)
@@ -45,6 +45,8 @@
 #include "config.h"
 #endif
 
+#include <assert.h>
+
 /* The autoconf on OpenBSD 4.5 produces the malformed constant name
  * SIZEOF_VOID__ rather than SIZEOF_VOID_P.  Work around that here. */
 #if !defined(SIZEOF_VOID_P) && defined(SIZEOF_VOID__)
@@ -75,6 +77,18 @@
     return __atomic_load_n(x, __ATOMIC_SEQ_CST);
 }
 
+static cairo_always_inline cairo_atomic_int_t
+_cairo_atomic_int_get_relaxed (cairo_atomic_int_t *x)
+{
+    return __atomic_load_n(x, __ATOMIC_RELAXED);
+}
+
+static cairo_always_inline void
+_cairo_atomic_int_set_relaxed (cairo_atomic_int_t *x, cairo_atomic_int_t val)
+{
+    __atomic_store_n(x, val, __ATOMIC_RELAXED);
+}
+
 static cairo_always_inline void *
 _cairo_atomic_ptr_get (void **x)
 {
@@ -143,13 +157,12 @@
 
 #endif
 
-#if HAVE_INTEL_ATOMIC_PRIMITIVES
+#if HAVE_GCC_LEGACY_ATOMICS
 
 #define HAS_ATOMIC_OPS 1
 
 typedef int cairo_atomic_int_t;
 
-#ifdef ATOMIC_OP_NEEDS_MEMORY_BARRIER
 static cairo_always_inline cairo_atomic_int_t
 _cairo_atomic_int_get (cairo_atomic_int_t *x)
 {
@@ -157,6 +170,18 @@
     return *x;
 }
 
+static cairo_always_inline cairo_atomic_int_t
+_cairo_atomic_int_get_relaxed (cairo_atomic_int_t *x)
+{
+    return *x;
+}
+
+static cairo_always_inline void
+_cairo_atomic_int_set_relaxed (cairo_atomic_int_t *x, cairo_atomic_int_t val)
+{
+    *x = val;
+}
+
 static cairo_always_inline void *
 _cairo_atomic_ptr_get (void **x)
 {
@@ -163,10 +188,6 @@
     __sync_synchronize ();
     return *x;
 }
-#else
-# define _cairo_atomic_int_get(x) (*x)
-# define _cairo_atomic_ptr_get(x) (*x)
-#endif
 
 # define _cairo_atomic_int_inc(x) ((void) __sync_fetch_and_add(x, 1))
 # define _cairo_atomic_int_dec(x) ((void) __sync_fetch_and_add(x, -1))
@@ -200,6 +221,8 @@
 typedef  AO_t cairo_atomic_int_t;
 
 # define _cairo_atomic_int_get(x) (AO_load_full (x))
+# define _cairo_atomic_int_get_relaxed(x) (AO_load_full (x))
+# define _cairo_atomic_int_set_relaxed(x, val) (AO_store_full ((x), (val)))
 
 # define _cairo_atomic_int_inc(x) ((void) AO_fetch_and_add1_full(x))
 # define _cairo_atomic_int_dec(x) ((void) AO_fetch_and_sub1_full(x))
@@ -230,6 +253,8 @@
 typedef int32_t cairo_atomic_int_t;
 
 # define _cairo_atomic_int_get(x) (OSMemoryBarrier(), *(x))
+# define _cairo_atomic_int_get_relaxed(x) *(x)
+# define _cairo_atomic_int_set_relaxed(x, val) *(x) = (val)
 
 # define _cairo_atomic_int_inc(x) ((void) OSAtomicIncrement32Barrier (x))
 # define _cairo_atomic_int_dec(x) ((void) OSAtomicDecrement32Barrier (x))
@@ -288,9 +313,15 @@
 #ifdef ATOMIC_OP_NEEDS_MEMORY_BARRIER
 cairo_private cairo_atomic_int_t
 _cairo_atomic_int_get (cairo_atomic_int_t *x);
+cairo_private cairo_atomic_int_t
+_cairo_atomic_int_get_relaxed (cairo_atomic_int_t *x);
+void
+_cairo_atomic_int_set_relaxed (cairo_atomic_int_t *x, cairo_atomic_int_t val);
 # define _cairo_atomic_ptr_get(x) (void *) _cairo_atomic_int_get((cairo_atomic_int_t *) x)
 #else
 # define _cairo_atomic_int_get(x) (*x)
+# define _cairo_atomic_int_get_relaxed(x) (*x)
+# define _cairo_atomic_int_set_relaxed(x, val) (*x) = (val)
 # define _cairo_atomic_ptr_get(x) (*x)
 #endif
 
@@ -357,6 +388,37 @@
     (void) ret__; \
 } while (0)
 
+typedef cairo_atomic_int_t cairo_atomic_once_t;
+
+#define CAIRO_ATOMIC_ONCE_UNINITIALIZED (0)
+#define CAIRO_ATOMIC_ONCE_INITIALIZING  (1)
+#define CAIRO_ATOMIC_ONCE_INITIALIZED   (2)
+#define CAIRO_ATOMIC_ONCE_INIT          CAIRO_ATOMIC_ONCE_UNINITIALIZED
+
+static cairo_always_inline cairo_bool_t
+_cairo_atomic_init_once_enter(cairo_atomic_once_t *once)
+{
+    if (likely(_cairo_atomic_int_get(once) == CAIRO_ATOMIC_ONCE_INITIALIZED))
+	return 0;
+
+    if (_cairo_atomic_int_cmpxchg(once,
+				  CAIRO_ATOMIC_ONCE_UNINITIALIZED,
+				  CAIRO_ATOMIC_ONCE_INITIALIZING))
+	return 1;
+
+    while (_cairo_atomic_int_get(once) != CAIRO_ATOMIC_ONCE_INITIALIZED) {}
+    return 0;
+}
+
+static cairo_always_inline void
+_cairo_atomic_init_once_leave(cairo_atomic_once_t *once)
+{
+    if (unlikely(!_cairo_atomic_int_cmpxchg(once,
+					    CAIRO_ATOMIC_ONCE_INITIALIZING,
+					    CAIRO_ATOMIC_ONCE_INITIALIZED)))
+	assert (0 && "incorrect use of _cairo_atomic_init_once API (once != CAIRO_ATOMIC_ONCE_INITIALIZING)");
+}
+
 CAIRO_END_DECLS
 
 #endif

Modified: trunk/Build/source/libs/cairo/cairo-src/src/cairo-atomic.c
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/src/cairo-atomic.c	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/src/cairo-atomic.c	2018-10-20 03:19:36 UTC (rev 48952)
@@ -101,6 +101,20 @@
 
     return ret;
 }
+
+cairo_atomic_intptr_t
+_cairo_atomic_int_get_relaxed (cairo_atomic_intptr_t *x)
+{
+    return _cairo_atomic_int_get (x);
+}
+
+void
+_cairo_atomic_int_set_relaxed (cairo_atomic_intptr_t *x, cairo_atomic_intptr_t val)
+{
+    CAIRO_MUTEX_LOCK (_cairo_atomic_mutex);
+    *x = val;
+    CAIRO_MUTEX_UNLOCK (_cairo_atomic_mutex);
+}
 #endif
 
 #endif

Modified: trunk/Build/source/libs/cairo/cairo-src/src/cairo-backend-private.h
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/src/cairo-backend-private.h	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/src/cairo-backend-private.h	2018-10-20 03:19:36 UTC (rev 48952)
@@ -172,6 +172,9 @@
 
     cairo_status_t (*copy_page) (void *cr);
     cairo_status_t (*show_page) (void *cr);
+
+    cairo_status_t (*tag_begin) (void *cr, const char *tag_name, const char *attributes);
+    cairo_status_t (*tag_end) (void *cr, const char *tag_name);
 };
 
 static inline void

Modified: trunk/Build/source/libs/cairo/cairo-src/src/cairo-base64-stream.c
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/src/cairo-base64-stream.c	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/src/cairo-base64-stream.c	2018-10-20 03:19:36 UTC (rev 48952)
@@ -125,7 +125,7 @@
     if (output->status)
 	return _cairo_output_stream_create_in_error (output->status);
 
-    stream = malloc (sizeof (cairo_base64_stream_t));
+    stream = _cairo_malloc (sizeof (cairo_base64_stream_t));
     if (unlikely (stream == NULL)) {
 	_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
 	return (cairo_output_stream_t *) &_cairo_output_stream_nil;

Modified: trunk/Build/source/libs/cairo/cairo-src/src/cairo-base85-stream.c
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/src/cairo-base85-stream.c	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/src/cairo-base85-stream.c	2018-10-20 03:19:36 UTC (rev 48952)
@@ -114,7 +114,7 @@
     if (output->status)
 	return _cairo_output_stream_create_in_error (output->status);
 
-    stream = malloc (sizeof (cairo_base85_stream_t));
+    stream = _cairo_malloc (sizeof (cairo_base85_stream_t));
     if (unlikely (stream == NULL)) {
 	_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
 	return (cairo_output_stream_t *) &_cairo_output_stream_nil;

Modified: trunk/Build/source/libs/cairo/cairo-src/src/cairo-bentley-ottmann-rectangular.c
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/src/cairo-bentley-ottmann-rectangular.c	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/src/cairo-bentley-ottmann-rectangular.c	2018-10-20 03:19:36 UTC (rev 48952)
@@ -593,12 +593,6 @@
     pqueue_push (sweep, rectangle);
 }
 
-static int
-sweep_line_setjmp (sweep_line_t *sweep_line)
-{
-    return setjmp (sweep_line->unwind);
-}
-
 static cairo_status_t
 _cairo_bentley_ottmann_tessellate_rectangular (rectangle_t	**rectangles,
 					       int			  num_rectangles,
@@ -609,15 +603,17 @@
     sweep_line_t sweep_line;
     rectangle_t *rectangle;
     cairo_status_t status;
-    cairo_bool_t update = FALSE;
+    cairo_bool_t update;
 
     sweep_line_init (&sweep_line,
 		     rectangles, num_rectangles,
 		     fill_rule,
 		     do_traps, container);
-    if ((status = sweep_line_setjmp (&sweep_line)))
+    if ((status = setjmp (sweep_line.unwind)))
 	return status;
 
+    update = FALSE;
+
     rectangle = rectangle_pop_start (&sweep_line);
     do {
 	if (rectangle->top != sweep_line.current_y) {
@@ -678,11 +674,20 @@
     cairo_status_t status;
     int i;
 
-    if (unlikely (traps->num_traps <= 1))
+   assert (traps->is_rectangular);
+
+    if (unlikely (traps->num_traps <= 1)) {
+        if (traps->num_traps == 1) {
+            cairo_trapezoid_t *trap = traps->traps;
+            if (trap->left.p1.x > trap->right.p1.x) {
+                cairo_line_t tmp = trap->left;
+                trap->left = trap->right;
+                trap->right = tmp;
+            }
+        }
 	return CAIRO_STATUS_SUCCESS;
+    }
 
-    assert (traps->is_rectangular);
-
     dump_traps (traps, "bo-rects-traps-in.txt");
 
     rectangles = stack_rectangles;

Modified: trunk/Build/source/libs/cairo/cairo-src/src/cairo-bentley-ottmann.c
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/src/cairo-bentley-ottmann.c	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/src/cairo-bentley-ottmann.c	2018-10-20 03:19:36 UTC (rev 48952)
@@ -1484,10 +1484,13 @@
 	ymin = _cairo_fixed_integer_floor (polygon->limit.p1.y);
 	ymax = _cairo_fixed_integer_ceil (polygon->limit.p2.y) - ymin;
 
-	if (ymax > 64)
+	if (ymax > 64) {
 	    event_y = _cairo_malloc_ab(sizeof (cairo_bo_event_t*), ymax);
-	else
+	    if (unlikely (event_y == NULL))
+		return _cairo_error (CAIRO_STATUS_NO_MEMORY);
+	} else {
 	    event_y = stack_event_y;
+	}
 	memset (event_y, 0, ymax * sizeof(cairo_bo_event_t *));
     }
 
@@ -1498,8 +1501,11 @@
 					  sizeof (cairo_bo_start_event_t) +
 					  sizeof (cairo_bo_event_t *),
 					  sizeof (cairo_bo_event_t *));
-	if (unlikely (events == NULL))
+	if (unlikely (events == NULL)) {
+	    if (event_y != stack_event_y)
+		free (event_y);
 	    return _cairo_error (CAIRO_STATUS_NO_MEMORY);
+	}
 
 	event_ptrs = (cairo_bo_event_t **) (events + num_events);
     }

Modified: trunk/Build/source/libs/cairo/cairo-src/src/cairo-botor-scan-converter.c
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/src/cairo-botor-scan-converter.c	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/src/cairo-botor-scan-converter.c	2018-10-20 03:19:36 UTC (rev 48952)
@@ -456,7 +456,7 @@
        HAVE_BX      = 0x2,
        HAVE_BOTH    = HAVE_AX | HAVE_BX
     } have_ax_bx = HAVE_BOTH;
-    int32_t ax, bx;
+    int32_t ax = 0, bx = 0;
 
     /* XXX given we have x and dx? */
 
@@ -2128,6 +2128,44 @@
     return CAIRO_STATUS_SUCCESS;
 }
 
+#if 0
+static cairo_status_t
+_cairo_botor_scan_converter_add_edge (void		*converter,
+				      const cairo_point_t *p1,
+				      const cairo_point_t *p2,
+				      int top, int bottom,
+				      int dir)
+{
+    cairo_botor_scan_converter_t *self = converter;
+    cairo_edge_t edge;
+
+    edge.line.p1 = *p1;
+    edge.line.p2 = *p2;
+    edge.top = top;
+    edge.bottom = bottom;
+    edge.dir = dir;
+
+    return botor_add_edge (self, &edge);
+}
+#endif
+
+cairo_status_t
+_cairo_botor_scan_converter_add_polygon (cairo_botor_scan_converter_t *converter,
+					 const cairo_polygon_t *polygon)
+{
+    cairo_botor_scan_converter_t *self = converter;
+    cairo_status_t status;
+    int i;
+
+    for (i = 0; i < polygon->num_edges; i++) {
+	status = botor_add_edge (self, &polygon->edges[i]);
+	if (unlikely (status))
+	    return status;
+    }
+
+    return CAIRO_STATUS_SUCCESS;
+}
+
 static void
 _cairo_botor_scan_converter_destroy (void *converter)
 {

Modified: trunk/Build/source/libs/cairo/cairo-src/src/cairo-box-inline.h
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/src/cairo-box-inline.h	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/src/cairo-box-inline.h	2018-10-20 03:19:36 UTC (rev 48952)
@@ -57,6 +57,16 @@
     box->p2.y = _cairo_fixed_from_int (y + h);
 }
 
+static inline void
+_cairo_box_from_rectangle_int (cairo_box_t *box,
+			       const cairo_rectangle_int_t *rect)
+{
+    box->p1.x = _cairo_fixed_from_int (rect->x);
+    box->p1.y = _cairo_fixed_from_int (rect->y);
+    box->p2.x = _cairo_fixed_from_int (rect->x + rect->width);
+    box->p2.y = _cairo_fixed_from_int (rect->y + rect->height);
+}
+
 /* assumes box->p1 is top-left, p2 bottom-right */
 static inline void
 _cairo_box_add_point (cairo_box_t *box,

Modified: trunk/Build/source/libs/cairo/cairo-src/src/cairo-boxes-private.h
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/src/cairo-boxes-private.h	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/src/cairo-boxes-private.h	2018-10-20 03:19:36 UTC (rev 48952)
@@ -92,8 +92,7 @@
 
 cairo_private cairo_box_t *
 _cairo_boxes_to_array (const cairo_boxes_t *boxes,
-		       int *num_boxes,
-		       cairo_bool_t force_allocation);
+		       int *num_boxes);
 
 cairo_private cairo_status_t
 _cairo_boxes_intersect (const cairo_boxes_t *a,

Modified: trunk/Build/source/libs/cairo/cairo-src/src/cairo-boxes.c
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/src/cairo-boxes.c	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/src/cairo-boxes.c	2018-10-20 03:19:36 UTC (rev 48952)
@@ -102,6 +102,17 @@
     boxes->is_pixel_aligned = n == num_boxes;
 }
 
+/** _cairo_boxes_limit:
+ *
+ * Computes the minimum bounding box of the given list of boxes and assign
+ * it to the given boxes set. It also assigns that list as the list of
+ * limiting boxes in the box set.
+ *
+ * @param boxes        the box set to be filled (return buffer)
+ * @param limits       array of the limiting boxes to compute the bounding
+ *                     box from
+ * @param num_limits   length of the limits array
+ */
 void
 _cairo_boxes_limit (cairo_boxes_t	*boxes,
 		    const cairo_box_t	*limits,
@@ -265,6 +276,14 @@
     return boxes->status;
 }
 
+/** _cairo_boxes_extents:
+ *
+ * Computes the minimum bounding box of the given box set and stores
+ * it in the given box.
+ *
+ * @param boxes      The box set whose minimum bounding is computed.
+ * @param box        Return buffer for the computed result.
+ */
 void
 _cairo_boxes_extents (const cairo_boxes_t *boxes,
 		      cairo_box_t *box)
@@ -317,10 +336,19 @@
     boxes->is_pixel_aligned = TRUE;
 }
 
+/** _cairo_boxes_to_array:
+ *
+ * Linearize a box set of possibly multiple chunks into one big chunk
+ * and returns an array of boxes
+ *
+ * @param boxes      The box set to be converted.
+ * @param num_boxes  Return buffer for the number of boxes (array count).
+ * @return           Pointer to the newly allocated array of boxes
+ *                   (the number o elements is given in num_boxes).
+ */
 cairo_box_t *
 _cairo_boxes_to_array (const cairo_boxes_t *boxes,
-		       int *num_boxes,
-		       cairo_bool_t force_allocation)
+		       int *num_boxes)
 {
     const struct _cairo_boxes_chunk *chunk;
     cairo_box_t *box;
@@ -327,8 +355,6 @@
     int i, j;
 
     *num_boxes = boxes->num_boxes;
-    if (boxes->chunks.next == NULL && ! force_allocation)
-	    return boxes->chunks.base;
 
     box = _cairo_malloc_ab (boxes->num_boxes, sizeof (cairo_box_t));
     if (box == NULL) {

Modified: trunk/Build/source/libs/cairo/cairo-src/src/cairo-cff-subset.c
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/src/cairo-cff-subset.c	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/src/cairo-cff-subset.c	2018-10-20 03:19:36 UTC (rev 48952)
@@ -295,21 +295,12 @@
 static unsigned char *
 decode_real (unsigned char *p, double *real)
 {
-    const char *decimal_point;
-    int decimal_point_len;
-    int n;
     char buffer[100];
-    char buffer2[200];
-    char *q;
     char *buf = buffer;
     char *buf_end = buffer + sizeof (buffer);
+    char *end;
+    int n;
 
-    decimal_point = cairo_get_locale_decimal_point ();
-    decimal_point_len = strlen (decimal_point);
-
-    assert (decimal_point_len != 0);
-    assert (sizeof(buffer) + decimal_point_len < sizeof(buffer2));
-
     p++;
     while (buf + 2 < buf_end) {
 	n = *p >> 4;
@@ -324,20 +315,8 @@
     };
     *buf = 0;
 
-    buf = buffer;
-    if (strchr (buffer, '.')) {
-	 q = strchr (buffer, '.');
-	 strncpy (buffer2, buffer, q - buffer);
-	 buf = buffer2 + (q - buffer);
-	 strncpy (buf, decimal_point, decimal_point_len);
-	 buf += decimal_point_len;
-	 strcpy (buf, q + 1);
-	 buf = buffer2;
-    }
+    *real = _cairo_strtod (buffer, &end);
 
-    if (sscanf(buf, "%lf", real) != 1)
-        *real = 0.0;
-
     return p;
 }
 
@@ -568,7 +547,7 @@
 
     element.length = length;
     element.is_copy = TRUE;
-    element.data = malloc (element.length);
+    element.data = _cairo_malloc (element.length);
     if (unlikely (element.data == NULL))
 	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
@@ -631,12 +610,12 @@
 {
     cff_dict_operator_t *op;
 
-    op = malloc (sizeof (cff_dict_operator_t));
+    op = _cairo_malloc (sizeof (cff_dict_operator_t));
     if (unlikely (op == NULL))
 	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
     _cairo_dict_init_key (op, operator);
-    op->operand = malloc (size);
+    op->operand = _cairo_malloc (size);
     if (unlikely (op->operand == NULL)) {
         free (op);
 	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
@@ -737,7 +716,7 @@
     op = _cairo_hash_table_lookup (dict, &key.base);
     if (op != NULL) {
         free (op->operand);
-        op->operand = malloc (size);
+        op->operand = _cairo_malloc (size);
 	if (unlikely (op->operand == NULL))
 	    return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
@@ -891,7 +870,7 @@
 		len -= 7;
 	    }
 	}
-        font->ps_name = malloc (len + 1);
+        font->ps_name = _cairo_malloc (len + 1);
         if (unlikely (font->ps_name == NULL))
             return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
@@ -1879,7 +1858,7 @@
     cairo_status_t status;
 
     font->num_fontdicts = 1;
-    font->fd_dict = malloc (sizeof (cairo_hash_table_t *));
+    font->fd_dict = _cairo_malloc (sizeof (cairo_hash_table_t *));
     if (unlikely (font->fd_dict == NULL))
 	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
@@ -1890,11 +1869,11 @@
 	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
     }
 
-    font->fd_subset_map = malloc (sizeof (int));
+    font->fd_subset_map = _cairo_malloc (sizeof (int));
     if (unlikely (font->fd_subset_map == NULL))
 	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
-    font->private_dict_offset = malloc (sizeof (int));
+    font->private_dict_offset = _cairo_malloc (sizeof (int));
     if (unlikely (font->private_dict_offset == NULL))
 	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
@@ -1989,7 +1968,7 @@
 	if (unlikely (status))
 	    return status;
     }  else {
-	font->private_dict_offset = malloc (sizeof (int));
+	font->private_dict_offset = _cairo_malloc (sizeof (int));
 	if (unlikely (font->private_dict_offset == NULL))
 	    return _cairo_error (CAIRO_STATUS_NO_MEMORY);
     }
@@ -2581,7 +2560,7 @@
 
     /* If the PS name is not found, create a CairoFont-x-y name. */
     if (font->ps_name == NULL) {
-        font->ps_name = malloc (30);
+        font->ps_name = _cairo_malloc (30);
         if (unlikely (font->ps_name == NULL))
 	    return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
@@ -2731,7 +2710,7 @@
 
     font->is_opentype = TRUE;
     font->data_length = data_length;
-    font->data = malloc (data_length);
+    font->data = _cairo_malloc (data_length);
     if (unlikely (font->data == NULL))
         return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
@@ -2766,7 +2745,7 @@
     font->font_name = NULL;
     font->is_opentype = FALSE;
     font->data_length = data_length;
-    font->data = malloc (data_length);
+    font->data = _cairo_malloc (data_length);
     if (unlikely (font->data == NULL))
         return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
@@ -2788,14 +2767,21 @@
 {
     const cairo_scaled_font_backend_t *backend;
     cairo_int_status_t status;
+    cairo_bool_t is_synthetic;
     cairo_cff_font_t *font;
 
     backend = scaled_font_subset->scaled_font->backend;
 
-    /* We need to use a fallback font generated from the synthesized outlines. */
-    if (backend->is_synthetic && backend->is_synthetic (scaled_font_subset->scaled_font))
-	return CAIRO_INT_STATUS_UNSUPPORTED;
+    /* We need to use a fallback font if this font differs from the CFF outlines. */
+    if (backend->is_synthetic) {
+	status = backend->is_synthetic (scaled_font_subset->scaled_font, &is_synthetic);
+	if (unlikely (status))
+	    return status;
 
+	if (is_synthetic)
+	    return CAIRO_INT_STATUS_UNSUPPORTED;
+    }
+
     font = calloc (1, sizeof (cairo_cff_font_t));
     if (unlikely (font == NULL))
         return _cairo_error (CAIRO_STATUS_NO_MEMORY);
@@ -2995,7 +2981,7 @@
     cff_subset->ascent = (double)font->ascent/font->units_per_em;
     cff_subset->descent = (double)font->descent/font->units_per_em;
 
-    cff_subset->data = malloc (length);
+    cff_subset->data = _cairo_malloc (length);
     if (unlikely (cff_subset->data == NULL)) {
 	status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
 	goto fail4;
@@ -3054,7 +3040,7 @@
 	(status = backend->load_truetype_table (scaled_font, TT_TAG_CFF,
 						0, NULL, &data_length)) == CAIRO_INT_STATUS_SUCCESS)
     {
-	data = malloc (data_length);
+	data = _cairo_malloc (data_length);
 	if (unlikely (data == NULL)) {
 	    status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
 	    return FALSE;
@@ -3071,7 +3057,7 @@
 	(status = backend->load_type1_data (scaled_font,
 					    0, NULL, &data_length)) == CAIRO_INT_STATUS_SUCCESS)
     {
-	data = malloc (data_length);
+	data = _cairo_malloc (data_length);
 	if (unlikely (data == NULL)) {
 	    status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
 	    return FALSE;
@@ -3144,7 +3130,7 @@
     cairo_status_t status;
     cairo_cff_font_t *font;
 
-    font = malloc (sizeof (cairo_cff_font_t));
+    font = _cairo_malloc (sizeof (cairo_cff_font_t));
     if (unlikely (font == NULL))
 	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
@@ -3330,7 +3316,7 @@
 	if (unlikely (status))
 	    return status;
     } else {
-	font->private_dict_offset = malloc (sizeof (int));
+	font->private_dict_offset = _cairo_malloc (sizeof (int));
 	if (unlikely (font->private_dict_offset == NULL))
 	    return _cairo_error (CAIRO_STATUS_NO_MEMORY);
     }
@@ -3407,7 +3393,7 @@
     cff_subset->ascent = (double)type2_subset.y_max/1000;
     cff_subset->descent = (double)type2_subset.y_min/1000;
 
-    cff_subset->data = malloc (length);
+    cff_subset->data = _cairo_malloc (length);
     if (unlikely (cff_subset->data == NULL)) {
 	status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
 	goto fail4;

Modified: trunk/Build/source/libs/cairo/cairo-src/src/cairo-clip-boxes.c
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/src/cairo-clip-boxes.c	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/src/cairo-clip-boxes.c	2018-10-20 03:19:36 UTC (rev 48952)
@@ -119,11 +119,7 @@
 {
     cairo_box_t box;
 
-    box.p1.x = _cairo_fixed_from_int (rect->x);
-    box.p1.y = _cairo_fixed_from_int (rect->y);
-    box.p2.x = _cairo_fixed_from_int (rect->x + rect->width);
-    box.p2.y = _cairo_fixed_from_int (rect->y + rect->height);
-
+    _cairo_box_from_rectangle_int (&box, rect);
     return _cairo_clip_contains_rectangle_box (clip, rect, &box);
 }
 
@@ -268,6 +264,34 @@
     return _cairo_clip_intersect_rectangle_box (clip, &r, box);
 }
 
+/* Copy a box set to a clip
+ *
+ * @param boxes  The box set to copy from.
+ * @param clip   The clip to copy to (return buffer).
+ * @returns      Zero if the allocation failed (the clip will be set to
+ *               all-clipped), otherwise non-zero.
+ */
+static cairo_bool_t
+_cairo_boxes_copy_to_clip (const cairo_boxes_t *boxes, cairo_clip_t *clip)
+{
+    /* XXX cow-boxes? */
+    if (boxes->num_boxes == 1) {
+	clip->boxes = &clip->embedded_box;
+	clip->boxes[0] = boxes->chunks.base[0];
+	clip->num_boxes = 1;
+	return TRUE;
+    }
+
+    clip->boxes = _cairo_boxes_to_array (boxes, &clip->num_boxes);
+    if (unlikely (clip->boxes == NULL))
+    {
+	_cairo_clip_set_all_clipped (clip);
+	return FALSE;
+    }
+
+    return TRUE;
+}
+
 cairo_clip_t *
 _cairo_clip_intersect_boxes (cairo_clip_t *clip,
 			     const cairo_boxes_t *boxes)
@@ -305,13 +329,10 @@
     if (boxes->num_boxes == 0) {
 	clip = _cairo_clip_set_all_clipped (clip);
 	goto out;
-    } else if (boxes->num_boxes == 1) {
-	clip->boxes = &clip->embedded_box;
-	clip->boxes[0] = boxes->chunks.base[0];
-	clip->num_boxes = 1;
-    } else {
-	clip->boxes = _cairo_boxes_to_array (boxes, &clip->num_boxes, TRUE);
     }
+
+    _cairo_boxes_copy_to_clip (boxes, clip);
+
     _cairo_boxes_extents (boxes, &limits);
 
     _cairo_box_round_to_rectangle (&limits, &extents);
@@ -347,10 +368,7 @@
     if (r->width == 0 || r->height == 0)
 	return _cairo_clip_set_all_clipped (clip);
 
-    box.p1.x = _cairo_fixed_from_int (r->x);
-    box.p1.y = _cairo_fixed_from_int (r->y);
-    box.p2.x = _cairo_fixed_from_int (r->x + r->width);
-    box.p2.y = _cairo_fixed_from_int (r->y + r->height);
+    _cairo_box_from_rectangle_int (&box, r);
 
     return _cairo_clip_intersect_rectangle_box (clip, r, &box);
 }
@@ -581,16 +599,8 @@
     if (clip == NULL)
 	return _cairo_clip_set_all_clipped (clip);
 
-    /* XXX cow-boxes? */
-    if(boxes->num_boxes == 1) {
-	clip->boxes = &clip->embedded_box;
-	clip->boxes[0] = boxes->chunks.base[0];
-	clip->num_boxes = 1;
-    } else {
-	clip->boxes = _cairo_boxes_to_array (boxes, &clip->num_boxes, TRUE);
-	if (clip->boxes == NULL)
-	    return _cairo_clip_set_all_clipped (clip);
-    }
+    if (unlikely (! _cairo_boxes_copy_to_clip (boxes, clip)))
+	return clip;
 
     _cairo_boxes_extents (boxes, &extents);
     _cairo_box_round_to_rectangle (&extents, &clip->extents);

Modified: trunk/Build/source/libs/cairo/cairo-src/src/cairo-clip-tor-scan-converter.c
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/src/cairo-clip-tor-scan-converter.c	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/src/cairo-clip-tor-scan-converter.c	2018-10-20 03:19:36 UTC (rev 48952)
@@ -29,7 +29,7 @@
  * The source is from commit 734c53237a867a773640bd5b64816249fa1730f8
  * of
  *
- *   http://gitweb.freedesktop.org/?p=users/joonas/glitter-paths
+ *   https://gitweb.freedesktop.org/?p=users/joonas/glitter-paths
  */
 /* Glitter-paths is a stand alone polygon rasteriser derived from
  * David Turner's reimplementation of Tor Anderssons's 15x17
@@ -465,7 +465,7 @@
 {
     struct _pool_chunk *p;
 
-    p = malloc(size + sizeof(struct _pool_chunk));
+    p = _cairo_malloc (size + sizeof(struct _pool_chunk));
     if (unlikely (NULL == p))
 	longjmp (*pool->jmp, _cairo_error (CAIRO_STATUS_NO_MEMORY));
 

Modified: trunk/Build/source/libs/cairo/cairo-src/src/cairo-clip.c
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/src/cairo-clip.c	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/src/cairo-clip.c	2018-10-20 03:19:36 UTC (rev 48952)
@@ -62,7 +62,7 @@
 
     clip_path = _freed_pool_get (&clip_path_pool);
     if (unlikely (clip_path == NULL)) {
-	clip_path = malloc (sizeof (cairo_clip_path_t));
+	clip_path = _cairo_malloc (sizeof (cairo_clip_path_t));
 	if (unlikely (clip_path == NULL))
 	    return NULL;
     }
@@ -108,7 +108,7 @@
 
     clip = _freed_pool_get (&clip_pool);
     if (unlikely (clip == NULL)) {
-	clip = malloc (sizeof (cairo_clip_t));
+	clip = _cairo_malloc (sizeof (cairo_clip_t));
 	if (unlikely (clip == NULL))
 	    return NULL;
     }
@@ -735,7 +735,7 @@
     if (status == CAIRO_STATUS_CLIP_NOT_REPRESENTABLE)
 	return (cairo_rectangle_list_t*) &_cairo_rectangles_not_representable;
 
-    list = malloc (sizeof (*list));
+    list = _cairo_malloc (sizeof (*list));
     if (unlikely (list == NULL)) {
 	status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
 	return (cairo_rectangle_list_t*) &_cairo_rectangles_nil;
@@ -795,7 +795,7 @@
     }
 
  DONE:
-    list = malloc (sizeof (cairo_rectangle_list_t));
+    list = _cairo_malloc (sizeof (cairo_rectangle_list_t));
     if (unlikely (list == NULL)) {
         free (rectangles);
 	return ERROR_LIST (CAIRO_STATUS_NO_MEMORY);

Modified: trunk/Build/source/libs/cairo/cairo-src/src/cairo-cogl-context.c
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/src/cairo-cogl-context.c	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/src/cairo-cogl-context.c	2018-10-20 03:19:36 UTC (rev 48952)
@@ -755,7 +755,7 @@
 
     cr = _freed_pool_get (&context_pool);
     if (unlikely (cr == NULL)) {
-	cr = malloc (sizeof (cairo_cogl_context_t));
+	cr = _cairo_malloc (sizeof (cairo_cogl_context_t));
 	if (unlikely (cr == NULL))
 	    return _cairo_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
     }

Modified: trunk/Build/source/libs/cairo/cairo-src/src/cairo-cogl-gradient.c
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/src/cairo-cogl-gradient.c	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/src/cairo-cogl-gradient.c	2018-10-20 03:19:36 UTC (rev 48952)
@@ -397,7 +397,7 @@
     }
 
     if (!gradient) {
-	gradient = malloc (sizeof (cairo_cogl_linear_gradient_t) +
+	gradient = _cairo_malloc (sizeof (cairo_cogl_linear_gradient_t) +
 			   sizeof (cairo_gradient_stop_t) * (n_stops - 1));
 	if (!gradient)
 	    return CAIRO_INT_STATUS_NO_MEMORY;
@@ -413,7 +413,7 @@
     } else
 	_cairo_cogl_linear_gradient_reference (gradient);
 
-    entry = malloc (sizeof (cairo_cogl_linear_texture_entry_t));
+    entry = _cairo_malloc (sizeof (cairo_cogl_linear_texture_entry_t));
     if (!entry) {
 	status = CAIRO_INT_STATUS_NO_MEMORY;
 	goto BAIL;

Modified: trunk/Build/source/libs/cairo/cairo-src/src/cairo-cogl-surface.c
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/src/cairo-cogl-surface.c	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/src/cairo-cogl-surface.c	2018-10-20 03:19:36 UTC (rev 48952)
@@ -517,7 +517,7 @@
 					   void **pointer)
 {
     /* XXX: In the Cogl journal we found it more efficient to have a pool of
-     * buffers that we re-cycle but for now we simply thow away our stack
+     * buffers that we re-cycle but for now we simply throw away our stack
      * buffer each time we flush. */
     if (unlikely (surface->buffer_stack &&
 		  (surface->buffer_stack_size - surface->buffer_stack_offset) < size)) {
@@ -1994,7 +1994,7 @@
     CAIRO_REFERENCE_COUNT_INIT (&meta->ref_count, 1);
     meta->cache_entry.hash = hash;
     meta->counter = 0;
-    meta_path = malloc (sizeof (cairo_path_fixed_t));
+    meta_path = _cairo_malloc (sizeof (cairo_path_fixed_t));
     if (!meta_path)
 	goto BAIL;
     /* FIXME: we should add a ref-counted wrapper for our user_paths
@@ -2248,7 +2248,7 @@
     meta->cache_entry.hash = hash;
     meta->counter = 0;
     CAIRO_REFERENCE_COUNT_INIT (&meta->ref_count, 1);
-    meta_path = malloc (sizeof (cairo_path_fixed_t));
+    meta_path = _cairo_malloc (sizeof (cairo_path_fixed_t));
     if (!meta_path)
 	goto BAIL;
     /* FIXME: we should add a ref-counted wrapper for our user_paths
@@ -2504,7 +2504,7 @@
     if (unlikely (status))
 	return _cairo_surface_create_in_error (status);
 
-    surface = malloc (sizeof (cairo_cogl_surface_t));
+    surface = _cairo_malloc (sizeof (cairo_cogl_surface_t));
     if (unlikely (surface == NULL))
         return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
 
@@ -2544,7 +2544,8 @@
     _cairo_surface_init (&surface->base,
                          &_cairo_cogl_surface_backend,
                          &dev->base,
-                         CAIRO_CONTENT_COLOR_ALPHA);
+                         CAIRO_CONTENT_COLOR_ALPHA,
+			 FALSE); /* is_vector */
 
     return &surface->base;
 }

Modified: trunk/Build/source/libs/cairo/cairo-src/src/cairo-compiler-private.h
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/src/cairo-compiler-private.h	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/src/cairo-compiler-private.h	2018-10-20 03:19:36 UTC (rev 48952)
@@ -69,7 +69,7 @@
  *   call sites.  The macro works by renaming `f' to an internal name
  *   in the symbol table and hiding that.  As far as cairo internal
  *   calls are concerned they're calling a library internal function
- *   and thus don't need to bounce via the PLT.
+ *   and thus don't need to bounce via the procedure linkage table (PLT).
  *
  * slim_hidden_def(f)
  *

Modified: trunk/Build/source/libs/cairo/cairo-src/src/cairo-composite-rectangles.c
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/src/cairo-composite-rectangles.c	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/src/cairo-composite-rectangles.c	2018-10-20 03:19:36 UTC (rev 48952)
@@ -97,7 +97,8 @@
     _cairo_composite_reduce_pattern (source, &extents->source_pattern);
 
     _cairo_pattern_get_extents (&extents->source_pattern.base,
-				&extents->source);
+				&extents->source,
+				surface->is_vector);
     if (extents->is_bounded & CAIRO_OPERATOR_BOUND_BY_SOURCE) {
 	if (! _cairo_rectangle_intersect (&extents->bounded, &extents->source))
 	    return FALSE;
@@ -146,10 +147,8 @@
 _cairo_composite_rectangles_intersect (cairo_composite_rectangles_t *extents,
 				       const cairo_clip_t *clip)
 {
-    cairo_bool_t ret;
-
-    ret = _cairo_rectangle_intersect (&extents->bounded, &extents->mask);
-    if (! ret && extents->is_bounded & CAIRO_OPERATOR_BOUND_BY_MASK)
+    if ((!_cairo_rectangle_intersect (&extents->bounded, &extents->mask)) &&
+        (extents->is_bounded & CAIRO_OPERATOR_BOUND_BY_MASK))
 	return CAIRO_INT_STATUS_NOTHING_TO_DO;
 
     if (extents->is_bounded == (CAIRO_OPERATOR_BOUND_BY_MASK | CAIRO_OPERATOR_BOUND_BY_SOURCE)) {
@@ -318,7 +317,7 @@
 
 cairo_int_status_t
 _cairo_composite_rectangles_init_for_mask (cairo_composite_rectangles_t *extents,
-					   cairo_surface_t*surface,
+					   cairo_surface_t              *surface,
 					   cairo_operator_t		 op,
 					   const cairo_pattern_t	*source,
 					   const cairo_pattern_t	*mask,
@@ -332,7 +331,7 @@
 
     extents->original_mask_pattern = mask;
     _cairo_composite_reduce_pattern (mask, &extents->mask_pattern);
-    _cairo_pattern_get_extents (&extents->mask_pattern.base, &extents->mask);
+    _cairo_pattern_get_extents (&extents->mask_pattern.base, &extents->mask, surface->is_vector);
 
     return _cairo_composite_rectangles_intersect (extents, clip);
 }
@@ -353,7 +352,7 @@
 	return CAIRO_INT_STATUS_NOTHING_TO_DO;
     }
 
-    _cairo_path_fixed_approximate_stroke_extents (path, style, ctm, &extents->mask);
+    _cairo_path_fixed_approximate_stroke_extents (path, style, ctm, surface->is_vector, &extents->mask);
 
     return _cairo_composite_rectangles_intersect (extents, clip);
 }

Modified: trunk/Build/source/libs/cairo/cairo-src/src/cairo-damage.c
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/src/cairo-damage.c	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/src/cairo-damage.c	2018-10-20 03:19:36 UTC (rev 48952)
@@ -51,7 +51,7 @@
 {
     cairo_damage_t *damage;
 
-    damage = malloc (sizeof (*damage));
+    damage = _cairo_malloc (sizeof (*damage));
     if (unlikely (damage == NULL)) {
 	_cairo_error_throw(CAIRO_STATUS_NO_MEMORY);
 	return (cairo_damage_t *) &__cairo_damage__nil;
@@ -122,7 +122,7 @@
     if (size < count)
 	size = (count + 64) & ~63;
 
-    chunk = malloc (sizeof (*chunk) + sizeof (cairo_box_t) * size);
+    chunk = _cairo_malloc (sizeof (*chunk) + sizeof (cairo_box_t) * size);
     if (unlikely (chunk == NULL)) {
 	_cairo_damage_destroy (damage);
 	return (cairo_damage_t *) &__cairo_damage__nil;
@@ -210,7 +210,7 @@
 
     boxes = damage->tail->base;
     if (damage->dirty > damage->tail->size) {
-	boxes = free_boxes = malloc (damage->dirty * sizeof (cairo_box_t));
+	boxes = free_boxes = _cairo_malloc (damage->dirty * sizeof (cairo_box_t));
 	if (unlikely (boxes == NULL)) {
 	    _cairo_damage_destroy (damage);
 	    return (cairo_damage_t *) &__cairo_damage__nil;

Modified: trunk/Build/source/libs/cairo/cairo-src/src/cairo-debug.c
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/src/cairo-debug.c	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/src/cairo-debug.c	2018-10-20 03:19:36 UTC (rev 48952)
@@ -86,6 +86,8 @@
 
     _cairo_image_reset_static_data ();
 
+    _cairo_image_compositor_reset_static_data ();
+
 #if CAIRO_HAS_DRM_SURFACE
     _cairo_drm_device_reset_static_data ();
 #endif
@@ -237,7 +239,7 @@
 }
 
 void
-_cairo_debug_print_path (FILE *stream, cairo_path_fixed_t *path)
+_cairo_debug_print_path (FILE *stream, const cairo_path_fixed_t *path)
 {
     cairo_status_t status;
     cairo_box_t box;
@@ -302,3 +304,20 @@
 
     }
 }
+
+void
+_cairo_debug_print_matrix (FILE *file, const cairo_matrix_t *matrix)
+{
+    fprintf (file, "[%g %g %g %g %g %g]\n",
+	     matrix->xx, matrix->yx,
+	     matrix->xy, matrix->yy,
+	     matrix->x0, matrix->y0);
+}
+
+void
+_cairo_debug_print_rect (FILE *file, const cairo_rectangle_int_t *rect)
+{
+    fprintf (file, "x: %d y: %d width: %d height: %d\n",
+	     rect->x, rect->y,
+	     rect->width, rect->height);
+}

Modified: trunk/Build/source/libs/cairo/cairo-src/src/cairo-default-context.c
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/src/cairo-default-context.c	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/src/cairo-default-context.c	2018-10-20 03:19:36 UTC (rev 48952)
@@ -1156,6 +1156,24 @@
 }
 
 static cairo_status_t
+_cairo_default_context_tag_begin (void *abstract_cr,
+				  const char *tag_name, const char *attributes)
+{
+    cairo_default_context_t *cr = abstract_cr;
+
+    return _cairo_gstate_tag_begin (cr->gstate, tag_name, attributes);
+}
+
+static cairo_status_t
+_cairo_default_context_tag_end (void *abstract_cr,
+				const char *tag_name)
+{
+    cairo_default_context_t *cr = abstract_cr;
+
+    return _cairo_gstate_tag_end (cr->gstate, tag_name);
+}
+
+static cairo_status_t
 _cairo_default_context_show_page (void *abstract_cr)
 {
     cairo_default_context_t *cr = abstract_cr;
@@ -1437,6 +1455,9 @@
 
     _cairo_default_context_copy_page,
     _cairo_default_context_show_page,
+
+    _cairo_default_context_tag_begin,
+    _cairo_default_context_tag_end,
 };
 
 cairo_status_t
@@ -1460,7 +1481,7 @@
 
     cr = _freed_pool_get (&context_pool);
     if (unlikely (cr == NULL)) {
-	cr = malloc (sizeof (cairo_default_context_t));
+	cr = _cairo_malloc (sizeof (cairo_default_context_t));
 	if (unlikely (cr == NULL))
 	    return _cairo_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
     }

Modified: trunk/Build/source/libs/cairo/cairo-src/src/cairo-deflate-stream.c
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/src/cairo-deflate-stream.c	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/src/cairo-deflate-stream.c	2018-10-20 03:19:36 UTC (rev 48952)
@@ -124,7 +124,7 @@
     if (output->status)
 	return _cairo_output_stream_create_in_error (output->status);
 
-    stream = malloc (sizeof (cairo_deflate_stream_t));
+    stream = _cairo_malloc (sizeof (cairo_deflate_stream_t));
     if (unlikely (stream == NULL)) {
 	_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
 	return (cairo_output_stream_t *) &_cairo_output_stream_nil;

Modified: trunk/Build/source/libs/cairo/cairo-src/src/cairo-device.c
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/src/cairo-device.c	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/src/cairo-device.c	2018-10-20 03:19:36 UTC (rev 48952)
@@ -159,6 +159,10 @@
     case CAIRO_STATUS_INVALID_MESH_CONSTRUCTION:
     case CAIRO_STATUS_DEVICE_FINISHED:
     case CAIRO_STATUS_JBIG2_GLOBAL_MISSING:
+    case CAIRO_STATUS_PNG_ERROR:
+    case CAIRO_STATUS_FREETYPE_ERROR:
+    case CAIRO_STATUS_WIN32_GDI_ERROR:
+    case CAIRO_STATUS_TAG_ERROR:
     default:
 	_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
 	return (cairo_device_t *) &_nil_device;
@@ -190,8 +194,8 @@
  * @device from being destroyed until a matching call to
  * cairo_device_destroy() is made.
  *
- * The number of references to a #cairo_device_t can be get using
- * cairo_device_get_reference_count().
+ * Use cairo_device_get_reference_count() to get the number of references
+ * to a #cairo_device_t.
  *
  * Return value: the referenced #cairo_device_t.
  *

Modified: trunk/Build/source/libs/cairo/cairo-src/src/cairo-directfb-surface.c
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/src/cairo-directfb-surface.c	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/src/cairo-directfb-surface.c	2018-10-20 03:19:36 UTC (rev 48952)
@@ -522,7 +522,8 @@
     _cairo_surface_init (&surface->image.base,
                          &_cairo_dfb_surface_backend,
 			 NULL, /* device */
-			 _directfb_format_to_content (format));
+			 _directfb_format_to_content (format),
+			 FALSE); /* is_vector */
 
     surface->image.pixman_format = pixman_format;
     surface->image.format = _cairo_format_from_pixman_format (pixman_format);

Modified: trunk/Build/source/libs/cairo/cairo-src/src/cairo-error-private.h
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/src/cairo-error-private.h	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/src/cairo-error-private.h	2018-10-20 03:19:36 UTC (rev 48952)
@@ -94,6 +94,10 @@
     CAIRO_INT_STATUS_INVALID_MESH_CONSTRUCTION,
     CAIRO_INT_STATUS_DEVICE_FINISHED,
     CAIRO_INT_STATUS_JBIG2_GLOBAL_MISSING,
+    CAIRO_INT_STATUS_PNG_ERROR,
+    CAIRO_INT_STATUS_FREETYPE_ERROR,
+    CAIRO_INT_STATUS_WIN32_GDI_ERROR,
+    CAIRO_INT_STATUS_TAG_ERROR,
 
     CAIRO_INT_STATUS_LAST_STATUS,
 

Modified: trunk/Build/source/libs/cairo/cairo-src/src/cairo-font-face-twin.c
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/src/cairo-font-face-twin.c	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/src/cairo-font-face-twin.c	2018-10-20 03:19:36 UTC (rev 48952)
@@ -288,7 +288,7 @@
 {
     twin_face_properties_t *props;
 
-    props = malloc (sizeof (twin_face_properties_t));
+    props = _cairo_malloc (sizeof (twin_face_properties_t));
     if (unlikely (props == NULL))
 	return NULL;
 
@@ -412,7 +412,7 @@
     cairo_status_t status;
     twin_scaled_properties_t *props;
 
-    props = malloc (sizeof (twin_scaled_properties_t));
+    props = _cairo_malloc (sizeof (twin_scaled_properties_t));
     if (unlikely (props == NULL))
 	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 

Modified: trunk/Build/source/libs/cairo/cairo-src/src/cairo-font-face.c
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/src/cairo-font-face.c	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/src/cairo-font-face.c	2018-10-20 03:19:36 UTC (rev 48952)
@@ -111,8 +111,8 @@
  * @font_face from being destroyed until a matching call to
  * cairo_font_face_destroy() is made.
  *
- * The number of references to a #cairo_font_face_t can be get using
- * cairo_font_face_get_reference_count().
+ * Use cairo_font_face_get_reference_count() to get the number of
+ * references to a #cairo_font_face_t.
  *
  * Return value: the referenced #cairo_font_face_t.
  *

Modified: trunk/Build/source/libs/cairo/cairo-src/src/cairo-font-options.c
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/src/cairo-font-options.c	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/src/cairo-font-options.c	2018-10-20 03:19:36 UTC (rev 48952)
@@ -55,7 +55,8 @@
     CAIRO_LCD_FILTER_DEFAULT,
     CAIRO_HINT_STYLE_DEFAULT,
     CAIRO_HINT_METRICS_DEFAULT,
-    CAIRO_ROUND_GLYPH_POS_DEFAULT
+    CAIRO_ROUND_GLYPH_POS_DEFAULT,
+    NULL
 };
 
 /**
@@ -73,6 +74,7 @@
     options->hint_style = CAIRO_HINT_STYLE_DEFAULT;
     options->hint_metrics = CAIRO_HINT_METRICS_DEFAULT;
     options->round_glyph_positions = CAIRO_ROUND_GLYPH_POS_DEFAULT;
+    options->variations = NULL;
 }
 
 void
@@ -85,6 +87,7 @@
     options->hint_style = other->hint_style;
     options->hint_metrics = other->hint_metrics;
     options->round_glyph_positions = other->round_glyph_positions;
+    options->variations = other->variations ? strdup (other->variations) : NULL;
 }
 
 /**
@@ -106,7 +109,7 @@
 {
     cairo_font_options_t *options;
 
-    options = malloc (sizeof (cairo_font_options_t));
+    options = _cairo_malloc (sizeof (cairo_font_options_t));
     if (!options) {
 	_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
 	return (cairo_font_options_t *) &_cairo_font_options_nil;
@@ -140,7 +143,7 @@
     if (cairo_font_options_status ((cairo_font_options_t *) original))
 	return (cairo_font_options_t *) &_cairo_font_options_nil;
 
-    options = malloc (sizeof (cairo_font_options_t));
+    options = _cairo_malloc (sizeof (cairo_font_options_t));
     if (!options) {
 	_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
 	return (cairo_font_options_t *) &_cairo_font_options_nil;
@@ -151,6 +154,12 @@
     return options;
 }
 
+void
+_cairo_font_options_fini (cairo_font_options_t *options)
+{
+    free (options->variations);
+}
+
 /**
  * cairo_font_options_destroy:
  * @options: a #cairo_font_options_t
@@ -166,6 +175,7 @@
     if (cairo_font_options_status (options))
 	return;
 
+    _cairo_font_options_fini (options);
     free (options);
 }
 
@@ -226,6 +236,24 @@
 	options->hint_metrics = other->hint_metrics;
     if (other->round_glyph_positions != CAIRO_ROUND_GLYPH_POS_DEFAULT)
 	options->round_glyph_positions = other->round_glyph_positions;
+
+    if (other->variations) {
+      if (options->variations) {
+        char *p;
+
+        /* 'merge' variations by concatenating - later entries win */
+        p = malloc (strlen (other->variations) + strlen (options->variations) + 2);
+        p[0] = 0;
+        strcat (p, options->variations);
+        strcat (p, ",");
+        strcat (p, other->variations);
+        free (options->variations);
+        options->variations = p;
+      }
+      else {
+        options->variations = strdup (other->variations);
+      }
+    }
 }
 slim_hidden_def (cairo_font_options_merge);
 
@@ -259,7 +287,10 @@
 	    options->lcd_filter == other->lcd_filter &&
 	    options->hint_style == other->hint_style &&
 	    options->hint_metrics == other->hint_metrics &&
-	    options->round_glyph_positions == other->round_glyph_positions);
+	    options->round_glyph_positions == other->round_glyph_positions &&
+            ((options->variations == NULL && other->variations == NULL) ||
+             (options->variations != NULL && other->variations != NULL &&
+              strcmp (options->variations, other->variations) == 0)));
 }
 slim_hidden_def (cairo_font_options_equal);
 
@@ -280,14 +311,19 @@
 unsigned long
 cairo_font_options_hash (const cairo_font_options_t *options)
 {
+    unsigned long hash = 0;
+
     if (cairo_font_options_status ((cairo_font_options_t *) options))
 	options = &_cairo_font_options_nil; /* force default values */
 
+    if (options->variations)
+      hash = _cairo_string_hash (options->variations, strlen (options->variations));
+
     return ((options->antialias) |
 	    (options->subpixel_order << 4) |
 	    (options->lcd_filter << 8) |
 	    (options->hint_style << 12) |
-	    (options->hint_metrics << 16));
+	    (options->hint_metrics << 16)) ^ hash;
 }
 slim_hidden_def (cairo_font_options_hash);
 
@@ -533,3 +569,54 @@
 
     return options->hint_metrics;
 }
+
+/**
+ * cairo_font_options_set_variations:
+ * @options: a #cairo_font_options_t
+ * @variations: the new font variations, or %NULL
+ *
+ * Sets the OpenType font variations for the font options object.
+ * Font variations are specified as a string with a format that
+ * is similar to the CSS font-variation-settings. The string contains
+ * a comma-separated list of axis assignments, which each assignment
+ * consists of a 4-character axis name and a value, separated by
+ * whitespace and optional equals sign.
+ *
+ * Examples:
+ *
+ * wght=200,wdth=140.5
+ *
+ * wght 200 , wdth 140.5
+ *
+ * Since: 1.16
+ **/
+void
+cairo_font_options_set_variations (cairo_font_options_t *options,
+                                   const char           *variations)
+{
+  char *tmp = variations ? strdup (variations) : NULL;
+  free (options->variations);
+  options->variations = tmp;
+}
+
+/**
+ * cairo_font_options_get_variations:
+ * @options: a #cairo_font_options_t
+ *
+ * Gets the OpenType font variations for the font options object.
+ * See cairo_font_options_set_variations() for details about the
+ * string format.
+ *
+ * Return value: the font variations for the font options object. The
+ *   returned string belongs to the @options and must not be modified.
+ *   It is valid until either the font options object is destroyed or
+ *   the font variations in this object is modified with
+ *   cairo_font_options_set_variations().
+ *
+ * Since: 1.16
+ **/
+const char *
+cairo_font_options_get_variations (cairo_font_options_t *options)
+{
+  return options->variations;
+}

Modified: trunk/Build/source/libs/cairo/cairo-src/src/cairo-freed-pool-private.h
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/src/cairo-freed-pool-private.h	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/src/cairo-freed-pool-private.h	2018-10-20 03:19:36 UTC (rev 48952)
@@ -51,7 +51,7 @@
 #define MAX_FREED_POOL_SIZE 16
 typedef struct {
     void *pool[MAX_FREED_POOL_SIZE];
-    int top;
+    cairo_atomic_int_t top;
 } freed_pool_t;
 
 static cairo_always_inline void *
@@ -81,13 +81,13 @@
     void *ptr;
     int i;
 
-    i = pool->top - 1;
+    i = _cairo_atomic_int_get_relaxed (&pool->top) - 1;
     if (i < 0)
 	i = 0;
 
     ptr = _atomic_fetch (&pool->pool[i]);
     if (likely (ptr != NULL)) {
-	pool->top = i;
+	_cairo_atomic_int_set_relaxed (&pool->top, i);
 	return ptr;
     }
 
@@ -103,11 +103,11 @@
 {
     int i;
 
-    i = pool->top;
+    i = _cairo_atomic_int_get_relaxed (&pool->top);
     if (likely (i < ARRAY_LENGTH (pool->pool) &&
 		_atomic_store (&pool->pool[i], ptr)))
     {
-	pool->top = i + 1;
+	_cairo_atomic_int_set_relaxed (&pool->top, i + 1);
 	return;
     }
 

Modified: trunk/Build/source/libs/cairo/cairo-src/src/cairo-freed-pool.c
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/src/cairo-freed-pool.c	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/src/cairo-freed-pool.c	2018-10-20 03:19:36 UTC (rev 48952)
@@ -50,13 +50,13 @@
     for (i = ARRAY_LENGTH (pool->pool); i--;) {
 	ptr = _atomic_fetch (&pool->pool[i]);
 	if (ptr != NULL) {
-	    pool->top = i;
+	    _cairo_atomic_int_set_relaxed (&pool->top, i);
 	    return ptr;
 	}
     }
 
     /* empty */
-    pool->top = 0;
+    _cairo_atomic_int_set_relaxed (&pool->top, 0);
     return NULL;
 }
 
@@ -67,13 +67,13 @@
 
     for (i = 0; i < ARRAY_LENGTH (pool->pool); i++) {
 	if (_atomic_store (&pool->pool[i], ptr)) {
-	    pool->top = i + 1;
+	    _cairo_atomic_int_set_relaxed (&pool->top, i + 1);
 	    return;
 	}
     }
 
     /* full */
-    pool->top = i;
+    _cairo_atomic_int_set_relaxed (&pool->top, i);
     free (ptr);
 }
 
@@ -87,7 +87,7 @@
 	pool->pool[i] = NULL;
     }
 
-    pool->top = 0;
+    _cairo_atomic_int_set_relaxed (&pool->top, 0);
 }
 
 #endif

Modified: trunk/Build/source/libs/cairo/cairo-src/src/cairo-freelist-private.h
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/src/cairo-freelist-private.h	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/src/cairo-freelist-private.h	2018-10-20 03:19:36 UTC (rev 48952)
@@ -133,7 +133,7 @@
 
     node->next = freepool->first_free_node;
     freepool->first_free_node = node;
-    VG (VALGRIND_MAKE_MEM_NOACCESS (node, freepool->nodesize));
+    VG (VALGRIND_MAKE_MEM_UNDEFINED (node, freepool->nodesize));
 }
 
 #endif /* CAIRO_FREELIST_H */

Modified: trunk/Build/source/libs/cairo/cairo-src/src/cairo-freelist.c
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/src/cairo-freelist.c	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/src/cairo-freelist.c	2018-10-20 03:19:36 UTC (rev 48952)
@@ -61,7 +61,7 @@
 	return node;
     }
 
-    return malloc (freelist->nodesize);
+    return _cairo_malloc (freelist->nodesize);
 }
 
 void *
@@ -80,7 +80,7 @@
     if (node) {
 	node->next = freelist->first_free_node;
 	freelist->first_free_node = node;
-	VG (VALGRIND_MAKE_MEM_NOACCESS (node, freelist->nodesize));
+	VG (VALGRIND_MAKE_MEM_UNDEFINED (node, freelist->nodesize));
     }
 }
 
@@ -97,7 +97,7 @@
     freepool->embedded_pool.rem = sizeof (freepool->embedded_data);
     freepool->embedded_pool.data = freepool->embedded_data;
 
-    VG (VALGRIND_MAKE_MEM_NOACCESS (freepool->embedded_data, sizeof (freepool->embedded_data)));
+    VG (VALGRIND_MAKE_MEM_UNDEFINED (freepool->embedded_data, sizeof (freepool->embedded_data)));
 }
 
 void
@@ -119,7 +119,7 @@
 	pool = next;
     }
 
-    VG (VALGRIND_MAKE_MEM_NOACCESS (freepool, sizeof (freepool)));
+    VG (VALGRIND_MAKE_MEM_UNDEFINED (freepool, sizeof (freepool)));
 }
 
 void *
@@ -139,7 +139,7 @@
 	else
 	    poolsize = (128 * freepool->nodesize + 8191) & -8192;
 
-	pool = malloc (sizeof (cairo_freelist_pool_t) + poolsize);
+	pool = _cairo_malloc (sizeof (cairo_freelist_pool_t) + poolsize);
 	if (unlikely (pool == NULL))
 	    return pool;
 
@@ -152,7 +152,7 @@
     pool->rem = poolsize - freepool->nodesize;
     pool->data = (uint8_t *) (pool + 1) + freepool->nodesize;
 
-    VG (VALGRIND_MAKE_MEM_NOACCESS (pool->data, pool->rem));
+    VG (VALGRIND_MAKE_MEM_UNDEFINED (pool->data, pool->rem));
 
     return pool + 1;
 }

Modified: trunk/Build/source/libs/cairo/cairo-src/src/cairo-ft-font.c
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/src/cairo-ft-font.c	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/src/cairo-ft-font.c	2018-10-20 03:19:36 UTC (rev 48952)
@@ -58,6 +58,7 @@
 #include FT_BITMAP_H
 #include FT_TRUETYPE_TABLES_H
 #include FT_XFREE86_H
+#include FT_MULTIPLE_MASTERS_H
 #if HAVE_FT_GLYPHSLOT_EMBOLDEN
 #include FT_SYNTHESIS_H
 #endif
@@ -92,7 +93,6 @@
 #define FT_LCD_FILTER_LEGACY	16
 #endif
 
-#define DOUBLE_TO_26_6(d) ((FT_F26Dot6)((d) * 64.0))
 #define DOUBLE_FROM_26_6(t) ((double)(t) / 64.0)
 #define DOUBLE_TO_16_16(d) ((FT_Fixed)((d) * 65536.0))
 #define DOUBLE_FROM_16_16(t) ((double)(t) / 65536.0)
@@ -168,6 +168,10 @@
     cairo_matrix_t current_shape;
     FT_Matrix Current_Shape;
 
+    unsigned int have_color_set  : 1;
+    unsigned int have_color      : 1;  /* true if the font contains color glyphs */
+    FT_Fixed *variations;              /* variation settings that FT_Face came */
+
     cairo_mutex_t mutex;
     int lock_count;
 
@@ -187,6 +191,21 @@
     unsigned int synth_flags;
 } cairo_ft_options_t;
 
+static void
+_cairo_ft_options_init_copy (cairo_ft_options_t       *options,
+                             const cairo_ft_options_t *other)
+{
+    _cairo_font_options_init_copy (&options->base, &other->base);
+    options->load_flags = other->load_flags;
+    options->synth_flags = other->synth_flags;
+}
+
+static void
+_cairo_ft_options_fini (cairo_ft_options_t *options)
+{
+    _cairo_font_options_fini (&options->base);
+}
+
 struct _cairo_ft_font_face {
     cairo_font_face_t base;
 
@@ -223,7 +242,10 @@
    * Populate as needed. */
   switch (error)
   {
-  default:		return CAIRO_STATUS_NO_MEMORY;
+  case FT_Err_Out_Of_Memory:
+      return CAIRO_STATUS_NO_MEMORY;
+  default:
+      return CAIRO_STATUS_FREETYPE_ERROR;
   }
 }
 
@@ -278,7 +300,7 @@
      * detect some other call path. */
     assert (cairo_ft_unscaled_font_map == NULL);
 
-    font_map = malloc (sizeof (cairo_ft_unscaled_font_map_t));
+    font_map = _cairo_malloc (sizeof (cairo_ft_unscaled_font_map_t));
     if (unlikely (font_map == NULL))
 	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
@@ -419,9 +441,27 @@
     _cairo_unscaled_font_init (&unscaled->base,
 			       &cairo_ft_unscaled_font_backend);
 
+    unscaled->variations = NULL;
+
     if (from_face) {
 	unscaled->from_face = TRUE;
-	_cairo_ft_unscaled_font_init_key (unscaled, TRUE, NULL, 0, face);
+	_cairo_ft_unscaled_font_init_key (unscaled, TRUE, NULL, id, face);
+
+
+        unscaled->have_color = FT_HAS_COLOR (face) != 0;
+        unscaled->have_color_set = TRUE;
+
+#ifdef HAVE_FT_GET_VAR_DESIGN_COORDINATES
+	{
+	    FT_MM_Var *ft_mm_var;
+	    if (0 == FT_Get_MM_Var (face, &ft_mm_var))
+	    {
+		unscaled->variations = calloc (ft_mm_var->num_axis, sizeof (FT_Fixed));
+		if (unscaled->variations)
+		    FT_Get_Var_Design_Coordinates (face, ft_mm_var->num_axis, unscaled->variations);
+	    }
+	}
+#endif
     } else {
 	char *filename_copy;
 
@@ -433,6 +473,8 @@
 	    return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
 	_cairo_ft_unscaled_font_init_key (unscaled, FALSE, filename_copy, id, NULL);
+
+	unscaled->have_color_set = FALSE;
     }
 
     unscaled->have_scale = FALSE;
@@ -463,6 +505,8 @@
     free (unscaled->filename);
     unscaled->filename = NULL;
 
+    free (unscaled->variations);
+
     CAIRO_MUTEX_FINI (unscaled->mutex);
 }
 
@@ -475,7 +519,7 @@
 
     if (unscaled_a->id == unscaled_b->id &&
 	unscaled_a->from_face == unscaled_b->from_face)
-    {
+     {
         if (unscaled_a->from_face)
 	    return unscaled_a->face == unscaled_b->face;
 
@@ -519,7 +563,7 @@
     }
 
     /* Otherwise create it and insert into hash table. */
-    unscaled = malloc (sizeof (cairo_ft_unscaled_font_t));
+    unscaled = _cairo_malloc (sizeof (cairo_ft_unscaled_font_t));
     if (unlikely (unscaled == NULL)) {
 	status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
 	goto UNWIND_FONT_MAP_LOCK;
@@ -596,7 +640,7 @@
 _cairo_ft_unscaled_font_create_from_face (FT_Face face,
 					  cairo_ft_unscaled_font_t **out)
 {
-    return _cairo_ft_unscaled_font_create_internal (TRUE, NULL, 0, face, out);
+    return _cairo_ft_unscaled_font_create_internal (TRUE, NULL, face->face_index, face, out);
 }
 
 static cairo_bool_t
@@ -700,6 +744,9 @@
 
     unscaled->face = face;
 
+    unscaled->have_color = FT_HAS_COLOR (face) != 0;
+    unscaled->have_color_set = TRUE;
+
     font_map->num_open_faces++;
 
     return face;
@@ -929,6 +976,11 @@
 	pitch = width * 4;
 	break;
 
+    case FT_PIXEL_MODE_BGRA:
+	/* each pixel is replicated into a 32-bit ARGB value */
+	pitch = width * 4;
+	break;
+
     default:  /* unsupported source format */
 	return -1;
     }
@@ -1086,7 +1138,7 @@
 	}
 	break;
 
-    default:  /* FT_PIXEL_MODE_LCD_V */
+    case FT_PIXEL_MODE_LCD_V:
 	/* convert vertical RGB into ARGB32 */
 	if (!bgr) {
 
@@ -1123,6 +1175,15 @@
 		}
 	    }
 	}
+	break;
+
+    case FT_PIXEL_MODE_BGRA:
+	for (h = height; h > 0; h--, srcLine += src_pitch, dstLine += pitch)
+	    memcpy (dstLine, srcLine, width * 4);
+	break;
+
+    default:
+	assert (0);
     }
 }
 
@@ -1228,7 +1289,6 @@
 	    component_alpha = TRUE;
 	}
 	break;
-#ifdef FT_LOAD_COLOR
     case FT_PIXEL_MODE_BGRA:
 	stride = width * 4;
 	if (own_buffer) {
@@ -1240,9 +1300,17 @@
 
 	    memcpy (data, bitmap->buffer, stride * height);
 	}
+
+	if (!_cairo_is_little_endian ())
+	{
+	    /* Byteswap. */
+	    unsigned int i, count = height * width;
+	    uint32_t *p = (uint32_t *) data;
+	    for (i = 0; i < count; i++)
+		p[i] = be32_to_cpu (p[i]);
+	}
 	format = CAIRO_FORMAT_ARGB32;
 	break;
-#endif
     case FT_PIXEL_MODE_GRAY2:
     case FT_PIXEL_MODE_GRAY4:
     convert:
@@ -1423,6 +1491,7 @@
 
 	(*surface) = (cairo_image_surface_t *)
 	    cairo_image_surface_create_for_data (NULL, format, 0, 0, 0);
+	pixman_image_set_component_alpha ((*surface)->pixman_image, TRUE);
 	if ((*surface)->base.status)
 	    return (*surface)->base.status;
     } else {
@@ -1647,6 +1716,10 @@
 
     old_image = (*surface);
     (*surface) = (cairo_image_surface_t *)image;
+
+    /* Note: we converted subpixel-rendered RGBA images to grayscale,
+     * so, no need to copy component alpha to new image. */
+
     cairo_surface_destroy (&old_image->base);
 
     cairo_surface_set_device_offset (&(*surface)->base,
@@ -1685,6 +1758,7 @@
 #ifdef FC_HINT_STYLE
     int hintstyle;
 #endif
+    char *variations;
 
     _cairo_font_options_init_default (&ft_options.base);
     ft_options.load_flags = FT_LOAD_DEFAULT;
@@ -1826,6 +1900,13 @@
     if (embolden)
 	ft_options.synth_flags |= CAIRO_FT_SYNTHESIZE_BOLD;
 
+#ifndef FC_FONT_VARIATIONS
+#define FC_FONT_VARIATIONS "fontvariations"
+#endif
+    if (FcPatternGetString (pattern, FC_FONT_VARIATIONS, 0, (FcChar8 **) &variations) == FcResultMatch) {
+      ft_options.base.variations = strdup (variations);
+    }
+
     *ret = ft_options;
 }
 #endif
@@ -1903,6 +1984,24 @@
 	}
     }
 
+    if (other->base.variations) {
+      if (options->base.variations) {
+        char *p;
+
+        /* 'merge' variations by concatenating - later entries win */
+        p = malloc (strlen (other->base.variations) + strlen (options->base.variations) + 2);
+        p[0] = 0;
+        strcat (p, other->base.variations);
+        strcat (p, ",");
+        strcat (p, options->base.variations);
+        free (options->base.variations);
+        options->base.variations = p;
+      }
+      else {
+        options->base.variations = strdup (other->base.variations);
+      }
+    }
+
     options->load_flags = load_flags | load_target;
     options->synth_flags = other->synth_flags;
 }
@@ -1928,7 +2027,7 @@
     if (unlikely (face == NULL)) /* backend error */
 	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
-    scaled_font = malloc (sizeof (cairo_ft_scaled_font_t));
+    scaled_font = _cairo_malloc (sizeof (cairo_ft_scaled_font_t));
     if (unlikely (scaled_font == NULL)) {
 	status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
 	goto FAIL;
@@ -2205,6 +2304,99 @@
     }
 }
 
+static void
+cairo_ft_apply_variations (FT_Face                 face,
+			   cairo_ft_scaled_font_t *scaled_font)
+{
+    FT_MM_Var *ft_mm_var;
+    FT_Error ret;
+    unsigned int instance_id = scaled_font->unscaled->id >> 16;
+
+    ret = FT_Get_MM_Var (face, &ft_mm_var);
+    if (ret == 0) {
+        FT_Fixed *current_coords;
+        FT_Fixed *coords;
+        unsigned int i;
+        const char *p;
+
+        coords = malloc (sizeof (FT_Fixed) * ft_mm_var->num_axis);
+	/* FIXME check coords. */
+
+	if (scaled_font->unscaled->variations)
+	{
+	    memcpy (coords, scaled_font->unscaled->variations, ft_mm_var->num_axis * sizeof (*coords));
+	}
+	else if (instance_id && instance_id <= ft_mm_var->num_namedstyles)
+	{
+	    FT_Var_Named_Style *instance = &ft_mm_var->namedstyle[instance_id - 1];
+	    memcpy (coords, instance->coords, ft_mm_var->num_axis * sizeof (*coords));
+	}
+	else
+	    for (i = 0; i < ft_mm_var->num_axis; i++)
+		coords[i] = ft_mm_var->axis[i].def;
+
+        p = scaled_font->ft_options.base.variations;
+        while (p && *p) {
+            const char *start;
+            const char *end, *end2;
+            FT_ULong tag;
+            double value;
+
+            while (_cairo_isspace (*p)) p++;
+
+            start = p;
+            end = strchr (p, ',');
+            if (end && (end - p < 6))
+                goto skip;
+
+            tag = FT_MAKE_TAG(p[0], p[1], p[2], p[3]);
+
+            p += 4;
+            while (_cairo_isspace (*p)) p++;
+            if (*p == '=') p++;
+
+            if (p - start < 5)
+                goto skip;
+
+            value = _cairo_strtod (p, (char **) &end2);
+
+            while (end2 && _cairo_isspace (*end2)) end2++;
+
+            if (end2 && (*end2 != ',' && *end2 != '\0'))
+                goto skip;
+
+            for (i = 0; i < ft_mm_var->num_axis; i++) {
+                if (ft_mm_var->axis[i].tag == tag) {
+                    coords[i] = (FT_Fixed)(value*65536);
+                    break;
+                }
+            }
+
+skip:
+            p = end ? end + 1 : NULL;
+        }
+
+        current_coords = malloc (sizeof (FT_Fixed) * ft_mm_var->num_axis);
+#ifdef HAVE_FT_GET_VAR_DESIGN_COORDINATES
+        ret = FT_Get_Var_Design_Coordinates (face, ft_mm_var->num_axis, current_coords);
+        if (ret == 0) {
+            for (i = 0; i < ft_mm_var->num_axis; i++) {
+              if (coords[i] != current_coords[i])
+                break;
+            }
+            if (i == ft_mm_var->num_axis)
+              goto done;
+        }
+#endif
+
+        FT_Set_Var_Design_Coordinates (face, ft_mm_var->num_axis, coords);
+done:
+        free (coords);
+        free (current_coords);
+        free (ft_mm_var);
+    }
+}
+
 static cairo_int_status_t
 _cairo_ft_scaled_glyph_load_glyph (cairo_ft_scaled_font_t *scaled_font,
 				   cairo_scaled_glyph_t   *scaled_glyph,
@@ -2227,6 +2419,8 @@
     if (unlikely (status))
 	return status;
 
+    cairo_ft_apply_variations (face, scaled_font);
+
     error = FT_Load_Glyph (face,
 			   _cairo_scaled_glyph_index(scaled_glyph),
 			   load_flags);
@@ -2279,8 +2473,10 @@
     load_flags |= FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH;
 
     if ((info & CAIRO_SCALED_GLYPH_INFO_PATH) != 0 &&
-	(info & CAIRO_SCALED_GLYPH_INFO_SURFACE) == 0)
+	(info & (CAIRO_SCALED_GLYPH_INFO_SURFACE |
+                 CAIRO_SCALED_GLYPH_INFO_COLOR_SURFACE)) == 0) {
 	load_flags |= FT_LOAD_NO_BITMAP;
+    }
 
     /*
      * Don't pass FT_LOAD_VERTICAL_LAYOUT to FT_Load_Glyph here as
@@ -2291,19 +2487,7 @@
 	vertical_layout = TRUE;
     }
 
-#ifdef FT_LOAD_COLOR
-    /* Color-glyph support:
-     *
-     * This flags needs plumbing through fontconfig (does it?), and
-     * maybe we should cache color and grayscale bitmaps separately
-     * such that users of the font (ie. the surface) can choose which
-     * version to use based on target content type.
-     *
-     * Moreover, none of our backends and compositors currently support
-     * color glyphs.  As such, this is currently disabled.
-     */
-    /* load_flags |= FT_LOAD_COLOR; */
-#endif
+    load_flags |= FT_LOAD_COLOR;
 
 
     if (info & CAIRO_SCALED_GLYPH_INFO_METRICS) {
@@ -2416,7 +2600,8 @@
 					 &fs_metrics);
     }
 
-    if ((info & CAIRO_SCALED_GLYPH_INFO_SURFACE) != 0) {
+LOAD:
+    if (info & (CAIRO_SCALED_GLYPH_INFO_SURFACE | CAIRO_SCALED_GLYPH_INFO_COLOR_SURFACE)) {
 	cairo_image_surface_t	*surface;
 
 	if (!scaled_glyph_loaded) {
@@ -2444,18 +2629,37 @@
 	    {
 		status = _transform_glyph_bitmap (&unscaled->current_shape,
 						  &surface);
-		if (unlikely (status))
-		    cairo_surface_destroy (&surface->base);
-	    }
+                if (unlikely (status))
+                    cairo_surface_destroy (&surface->base);
+            }
 	}
 	if (unlikely (status))
 	    goto FAIL;
 
-	_cairo_scaled_glyph_set_surface (scaled_glyph,
-					 &scaled_font->base,
-					 surface);
+        if (pixman_image_get_format (surface->pixman_image) == PIXMAN_a8r8g8b8 &&
+            !pixman_image_get_component_alpha (surface->pixman_image)) {
+            _cairo_scaled_glyph_set_color_surface (scaled_glyph,
+                                                   &scaled_font->base,
+                                                   surface);
+        } else {
+            _cairo_scaled_glyph_set_surface (scaled_glyph,
+                                             &scaled_font->base,
+                                             surface);
+        }
     }
 
+    if (((info & (CAIRO_SCALED_GLYPH_INFO_SURFACE | CAIRO_SCALED_GLYPH_INFO_COLOR_SURFACE)) != 0) &&
+        ((scaled_glyph->has_info & CAIRO_SCALED_GLYPH_INFO_SURFACE) == 0)) {
+        /*
+         * A kludge -- load again, without color.
+         * No need to load the metrics again, though
+         */
+	scaled_glyph_loaded = FALSE;
+        info &= ~CAIRO_SCALED_GLYPH_INFO_METRICS;
+        load_flags &= ~FT_LOAD_COLOR;
+        goto LOAD;
+    }
+
     if (info & CAIRO_SCALED_GLYPH_INFO_PATH) {
 	cairo_path_fixed_t *path = NULL; /* hide compiler warning */
 
@@ -2463,7 +2667,7 @@
 	 * A kludge -- the above code will trash the outline,
 	 * so reload it. This will probably never occur though
 	 */
-	if ((info & CAIRO_SCALED_GLYPH_INFO_SURFACE) != 0) {
+	if ((info & (CAIRO_SCALED_GLYPH_INFO_SURFACE | CAIRO_SCALED_GLYPH_INFO_COLOR_SURFACE)) != 0) {
 	    scaled_glyph_loaded = FALSE;
 	    load_flags |= FT_LOAD_NO_BITMAP;
 	}
@@ -2592,11 +2796,79 @@
     return CAIRO_STATUS_SUCCESS;
 }
 
-static cairo_bool_t
-_cairo_ft_is_synthetic (void	        *abstract_font)
+static cairo_int_status_t
+_cairo_ft_is_synthetic (void	        *abstract_font,
+			cairo_bool_t    *is_synthetic)
 {
+    cairo_int_status_t status = CAIRO_STATUS_SUCCESS;
     cairo_ft_scaled_font_t *scaled_font = abstract_font;
-    return scaled_font->ft_options.synth_flags != 0;
+    cairo_ft_unscaled_font_t *unscaled = scaled_font->unscaled;
+    FT_Face face;
+    FT_Error error;
+
+    if (scaled_font->ft_options.synth_flags != 0) {
+	*is_synthetic = TRUE;
+	return status;
+    }
+
+    *is_synthetic = FALSE;
+    face = _cairo_ft_unscaled_font_lock_face (unscaled);
+    if (!face)
+	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
+
+    if (face->face_flags & FT_FACE_FLAG_MULTIPLE_MASTERS) {
+	FT_MM_Var *mm_var = NULL;
+	FT_Fixed *coords = NULL;
+	int num_axis;
+
+	/* If this is an MM or variable font we can't assume the current outlines
+	 * are the same as the font tables */
+	*is_synthetic = TRUE;
+
+	error = FT_Get_MM_Var (face, &mm_var);
+	if (error) {
+	    status = _cairo_error (_ft_to_cairo_error (error));
+	    goto cleanup;
+	}
+
+	num_axis = mm_var->num_axis;
+	coords = _cairo_malloc_ab (num_axis, sizeof(FT_Fixed));
+	if (!coords) {
+	    status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
+	    goto cleanup;
+	}
+
+#if FREETYPE_MAJOR > 2 || ( FREETYPE_MAJOR == 2 &&  FREETYPE_MINOR >= 8)
+	/* If FT_Get_Var_Blend_Coordinates() is available, we can check if the
+	 * current design coordinates are the default coordinates. In this case
+	 * the current outlines match the font tables.
+	 */
+	{
+	    int i;
+
+	    FT_Get_Var_Blend_Coordinates (face, num_axis, coords);
+	    *is_synthetic = FALSE;
+	    for (i = 0; i < num_axis; i++) {
+		if (coords[i]) {
+		    *is_synthetic = TRUE;
+		    break;
+		}
+	    }
+	}
+#endif
+
+      cleanup:
+	free (coords);
+#if HAVE_FT_DONE_MM_VAR
+	FT_Done_MM_Var (face->glyph->library, mm_var);
+#else
+	free (mm_var);
+#endif
+    }
+
+    _cairo_ft_unscaled_font_unlock_face (unscaled);
+
+    return status;
 }
 
 static cairo_int_status_t
@@ -2738,6 +3010,22 @@
     return status;
 }
 
+static cairo_bool_t
+_cairo_ft_has_color_glyphs (void *scaled)
+{
+    cairo_ft_unscaled_font_t *unscaled = ((cairo_ft_scaled_font_t *)scaled)->unscaled;
+
+    if (!unscaled->have_color_set) {
+	FT_Face face;
+	face = _cairo_ft_unscaled_font_lock_face (unscaled);
+	if (unlikely (face == NULL))
+	    return FALSE;
+	_cairo_ft_unscaled_font_unlock_face (unscaled);
+    }
+
+    return unscaled->have_color;
+}
+
 static const cairo_scaled_font_backend_t _cairo_ft_scaled_font_backend = {
     CAIRO_FONT_TYPE_FT,
     _cairo_ft_scaled_font_fini,
@@ -2748,7 +3036,8 @@
     _cairo_ft_index_to_ucs4,
     _cairo_ft_is_synthetic,
     _cairo_index_to_glyph_name,
-    _cairo_ft_load_type1_data
+    _cairo_ft_load_type1_data,
+    _cairo_ft_has_color_glyphs
 };
 
 /* #cairo_ft_font_face_t */
@@ -2879,6 +3168,8 @@
 	font_face->unscaled = NULL;
     }
 
+    _cairo_ft_options_fini (&font_face->ft_options);
+
 #if CAIRO_HAS_FC_FONT
     if (font_face->pattern) {
 	FcPatternDestroy (font_face->pattern);
@@ -2964,7 +3255,7 @@
 {
     cairo_ft_font_face_t *font_face;
 
-    font_face = malloc (sizeof (cairo_ft_font_face_t));
+    font_face = _cairo_malloc (sizeof (cairo_ft_font_face_t));
     if (unlikely (font_face == NULL)) {
 	_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
 	return (cairo_font_face_t *) &_cairo_font_face_nil;
@@ -2971,6 +3262,9 @@
     }
 
     font_face->unscaled = NULL;
+
+    _get_pattern_ft_options (pattern, &font_face->ft_options);
+
     font_face->next = NULL;
 
     font_face->pattern = FcPatternDuplicate (pattern);
@@ -3023,7 +3317,7 @@
     }
 
     /* No match found, create a new one */
-    font_face = malloc (sizeof (cairo_ft_font_face_t));
+    font_face = _cairo_malloc (sizeof (cairo_ft_font_face_t));
     if (unlikely (!font_face)) {
 	_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
 	return (cairo_font_face_t *)&_cairo_font_face_nil;
@@ -3032,7 +3326,7 @@
     font_face->unscaled = unscaled;
     _cairo_unscaled_font_reference (&unscaled->base);
 
-    font_face->ft_options = *ft_options;
+    _cairo_ft_options_init_copy (&font_face->ft_options, ft_options);
 
     if (unscaled->faces && unscaled->faces->unscaled == NULL) {
 	/* This "zombie" font_face (from _cairo_ft_font_face_destroy)
@@ -3279,6 +3573,7 @@
 
     _get_pattern_ft_options (resolved, &ft_options);
     font_face = _cairo_ft_font_face_create (unscaled, &ft_options);
+     _cairo_ft_options_fini (&ft_options);
     _cairo_unscaled_font_destroy (&unscaled->base);
 
 FREE_RESOLVED:
@@ -3353,6 +3648,7 @@
 
     _get_pattern_ft_options (pattern, &ft_options);
     font_face = _cairo_ft_font_face_create (unscaled, &ft_options);
+    _cairo_ft_options_fini (&ft_options);
     _cairo_unscaled_font_destroy (&unscaled->base);
 
     return font_face;
@@ -3506,7 +3802,8 @@
  *   cairo_ft_font_face_create_for_ft_face()).
  *
  * cairo_ft_scaled_font_lock_face() gets the #FT_Face object from a FreeType
- * backend font and scales it appropriately for the font. You must
+ * backend font and scales it appropriately for the font and applies OpenType
+ * font variations if applicable. You must
  * release the face with cairo_ft_scaled_font_unlock_face()
  * when you are done using it.  Since the #FT_Face object can be
  * shared between multiple #cairo_scaled_font_t objects, you must not
@@ -3559,6 +3856,8 @@
 	return NULL;
     }
 
+    cairo_ft_apply_variations (face, scaled_font);
+
     /* Note: We deliberately release the unscaled font's mutex here,
      * so that we are not holding a lock across two separate calls to
      * cairo function, (which would give the application some

Modified: trunk/Build/source/libs/cairo/cairo-src/src/cairo-gl-composite.c
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/src/cairo-gl-composite.c	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/src/cairo-gl-composite.c	2018-10-20 03:19:36 UTC (rev 48952)
@@ -52,9 +52,96 @@
 #include "cairo-error-private.h"
 #include "cairo-image-surface-private.h"
 
+/* FIXME: Copy of same routine in cairo-gl-msaa-compositor.c */
+static cairo_int_status_t
+_draw_int_rect (cairo_gl_context_t      *ctx,
+		cairo_gl_composite_t    *setup,
+		cairo_rectangle_int_t   *rect)
+{
+    cairo_box_t box;
+    cairo_point_t quad[4];
+
+    _cairo_box_from_rectangle (&box, rect);
+    quad[0].x = box.p1.x;
+    quad[0].y = box.p1.y;
+    quad[1].x = box.p1.x;
+    quad[1].y = box.p2.y;
+    quad[2].x = box.p2.x;
+    quad[2].y = box.p2.y;
+    quad[3].x = box.p2.x;
+    quad[3].y = box.p1.y;
+
+    return _cairo_gl_composite_emit_quad_as_tristrip (ctx, setup, quad);
+}
+
+static cairo_int_status_t
+_blit_texture_to_renderbuffer (cairo_gl_surface_t *surface)
+{
+    cairo_gl_context_t *ctx = NULL;
+    cairo_gl_composite_t setup;
+    cairo_surface_pattern_t pattern;
+    cairo_rectangle_int_t extents;
+    cairo_int_status_t status;
+
+    /* FIXME: This only permits blit when glesv3 is enabled.  But note that
+       glesv2 with the ANGLE extension should also be able to support this feature,
+       so once the ANGLE support code is in place this check can be relaxed. */
+    if (((cairo_gl_context_t *)surface->base.device)->gl_flavor != CAIRO_GL_FLAVOR_ES3)
+	return CAIRO_INT_STATUS_SUCCESS;
+
+    if (! surface->content_in_texture)
+	return CAIRO_INT_STATUS_SUCCESS;
+
+    memset (&setup, 0, sizeof (cairo_gl_composite_t));
+
+    status = _cairo_gl_composite_set_operator (&setup,
+					       CAIRO_OPERATOR_SOURCE,
+					       FALSE);
+
+    if (status)
+	return status;
+
+    setup.dst = surface;
+    setup.clip_region = surface->clip_region;
+
+    _cairo_pattern_init_for_surface (&pattern, &surface->base);
+    status = _cairo_gl_composite_set_source (&setup, &pattern.base,
+					     NULL, NULL, FALSE);
+    _cairo_pattern_fini (&pattern.base);
+
+    if (unlikely (status))
+	goto FAIL;
+
+    _cairo_gl_composite_set_multisample (&setup);
+
+    status = _cairo_gl_composite_begin (&setup, &ctx);
+
+    if (unlikely (status))
+	goto FAIL;
+
+    extents.x = extents.y = 0;
+    extents.width = surface->width;
+    extents.height = surface->height;
+
+    status = _draw_int_rect (ctx, &setup, &extents);
+
+    if (status == CAIRO_INT_STATUS_SUCCESS)
+	surface->content_in_texture = FALSE;
+
+FAIL:
+    _cairo_gl_composite_fini (&setup);
+
+    if (ctx) {
+	_cairo_gl_composite_flush (ctx);
+	status = _cairo_gl_context_release (ctx, status);
+    }
+
+    return status;
+}
+
 cairo_int_status_t
 _cairo_gl_composite_set_source (cairo_gl_composite_t *setup,
-			        const cairo_pattern_t *pattern,
+				const cairo_pattern_t *pattern,
 				const cairo_rectangle_int_t *sample,
 				const cairo_rectangle_int_t *extents,
 				cairo_bool_t use_texgen)
@@ -68,8 +155,13 @@
 _cairo_gl_composite_set_source_operand (cairo_gl_composite_t *setup,
 					const cairo_gl_operand_t *source)
 {
+    cairo_int_status_t status;
+
     _cairo_gl_operand_destroy (&setup->src);
     _cairo_gl_operand_copy (&setup->src, source);
+
+    if (source->type == CAIRO_GL_OPERAND_TEXTURE)
+	status = _cairo_gl_surface_resolve_multisampling (source->texture.surface);
 }
 
 void
@@ -89,7 +181,7 @@
 {
     _cairo_gl_operand_destroy (&setup->mask);
     if (pattern == NULL)
-        return CAIRO_STATUS_SUCCESS;
+	return CAIRO_STATUS_SUCCESS;
 
     return _cairo_gl_operand_init (&setup->mask, pattern, setup->dst,
 				   sample, extents, use_texgen);
@@ -99,9 +191,13 @@
 _cairo_gl_composite_set_mask_operand (cairo_gl_composite_t *setup,
 				      const cairo_gl_operand_t *mask)
 {
+    cairo_int_status_t status;
     _cairo_gl_operand_destroy (&setup->mask);
-    if (mask)
+    if (mask) {
 	_cairo_gl_operand_copy (&setup->mask, mask);
+	if (mask->type == CAIRO_GL_OPERAND_TEXTURE)
+	    status = _cairo_gl_surface_resolve_multisampling (mask->texture.surface);
+    }
 }
 
 void
@@ -118,7 +214,7 @@
 
 void
 _cairo_gl_composite_set_clip_region (cairo_gl_composite_t *setup,
-                                     cairo_region_t *clip_region)
+				     cairo_region_t *clip_region)
 {
     setup->clip_region = clip_region;
 }
@@ -142,8 +238,8 @@
 
 static void
 _cairo_gl_texture_set_filter (cairo_gl_context_t *ctx,
-                              GLuint              target,
-                              cairo_filter_t      filter)
+			      GLuint              target,
+			      cairo_filter_t      filter)
 {
     switch (filter) {
     case CAIRO_FILTER_FAST:
@@ -165,16 +261,17 @@
 
 static void
 _cairo_gl_texture_set_extend (cairo_gl_context_t *ctx,
-                              GLuint              target,
-                              cairo_extend_t      extend)
+			      GLuint              target,
+			      cairo_extend_t      extend)
 {
     GLint wrap_mode;
     assert (! _cairo_gl_device_requires_power_of_two_textures (&ctx->base) ||
-            (extend != CAIRO_EXTEND_REPEAT && extend != CAIRO_EXTEND_REFLECT));
+	    (extend != CAIRO_EXTEND_REPEAT && extend != CAIRO_EXTEND_REFLECT));
 
     switch (extend) {
     case CAIRO_EXTEND_NONE:
-	if (ctx->gl_flavor == CAIRO_GL_FLAVOR_ES)
+	if (ctx->gl_flavor == CAIRO_GL_FLAVOR_ES3 ||
+	    ctx->gl_flavor == CAIRO_GL_FLAVOR_ES2)
 	    wrap_mode = GL_CLAMP_TO_EDGE;
 	else
 	    wrap_mode = GL_CLAMP_TO_BORDER;
@@ -207,10 +304,10 @@
 
 static void
 _cairo_gl_context_setup_operand (cairo_gl_context_t *ctx,
-                                 cairo_gl_tex_t      tex_unit,
-                                 cairo_gl_operand_t *operand,
-                                 unsigned int        vertex_offset,
-                                 cairo_bool_t        vertex_size_changed)
+				 cairo_gl_tex_t      tex_unit,
+				 cairo_gl_operand_t *operand,
+				 unsigned int        vertex_offset,
+				 cairo_bool_t        vertex_size_changed)
 {
     cairo_gl_dispatch_t *dispatch = &ctx->dispatch;
     cairo_bool_t needs_setup;
@@ -219,12 +316,12 @@
      * to no shaders (or back) */
     needs_setup = vertex_size_changed;
     needs_setup |= _cairo_gl_operand_needs_setup (&ctx->operands[tex_unit],
-                                                 operand,
-                                                 vertex_offset);
+						 operand,
+						 vertex_offset);
 
     if (needs_setup) {
-        _cairo_gl_composite_flush (ctx);
-        _cairo_gl_context_destroy_operand (ctx, tex_unit);
+	_cairo_gl_composite_flush (ctx);
+	_cairo_gl_context_destroy_operand (ctx, tex_unit);
     }
 
     memcpy (&ctx->operands[tex_unit], operand, sizeof (cairo_gl_operand_t));
@@ -231,24 +328,24 @@
     ctx->operands[tex_unit].vertex_offset = vertex_offset;
 
     if (! needs_setup)
-        return;
+	return;
 
     switch (operand->type) {
     default:
     case CAIRO_GL_OPERAND_COUNT:
-        ASSERT_NOT_REACHED;
+	ASSERT_NOT_REACHED;
     case CAIRO_GL_OPERAND_NONE:
-        break;
-        /* fall through */
+	break;
+	/* fall through */
     case CAIRO_GL_OPERAND_CONSTANT:
-        break;
+	break;
     case CAIRO_GL_OPERAND_TEXTURE:
-        glActiveTexture (GL_TEXTURE0 + tex_unit);
-        glBindTexture (ctx->tex_target, operand->texture.tex);
-        _cairo_gl_texture_set_extend (ctx, ctx->tex_target,
-                                      operand->texture.attributes.extend);
-        _cairo_gl_texture_set_filter (ctx, ctx->tex_target,
-                                      operand->texture.attributes.filter);
+	glActiveTexture (GL_TEXTURE0 + tex_unit);
+	glBindTexture (ctx->tex_target, operand->texture.tex);
+	_cairo_gl_texture_set_extend (ctx, ctx->tex_target,
+				      operand->texture.attributes.extend);
+	_cairo_gl_texture_set_filter (ctx, ctx->tex_target,
+				      operand->texture.attributes.filter);
 
 	if (! operand->texture.texgen) {
 	    dispatch->VertexAttribPointer (CAIRO_GL_TEXCOORD0_ATTRIB_INDEX + tex_unit, 2,
@@ -256,15 +353,15 @@
 					   ctx->vb + vertex_offset);
 	    dispatch->EnableVertexAttribArray (CAIRO_GL_TEXCOORD0_ATTRIB_INDEX + tex_unit);
 	}
-        break;
+	break;
     case CAIRO_GL_OPERAND_LINEAR_GRADIENT:
     case CAIRO_GL_OPERAND_RADIAL_GRADIENT_A0:
     case CAIRO_GL_OPERAND_RADIAL_GRADIENT_NONE:
     case CAIRO_GL_OPERAND_RADIAL_GRADIENT_EXT:
-        glActiveTexture (GL_TEXTURE0 + tex_unit);
-        glBindTexture (ctx->tex_target, operand->gradient.gradient->tex);
-        _cairo_gl_texture_set_extend (ctx, ctx->tex_target, operand->gradient.extend);
-        _cairo_gl_texture_set_filter (ctx, ctx->tex_target, CAIRO_FILTER_BILINEAR);
+	glActiveTexture (GL_TEXTURE0 + tex_unit);
+	glBindTexture (ctx->tex_target, operand->gradient.gradient->tex);
+	_cairo_gl_texture_set_extend (ctx, ctx->tex_target, operand->gradient.extend);
+	_cairo_gl_texture_set_filter (ctx, ctx->tex_target, CAIRO_FILTER_BILINEAR);
 
 	if (! operand->gradient.texgen) {
 	    dispatch->VertexAttribPointer (CAIRO_GL_TEXCOORD0_ATTRIB_INDEX + tex_unit, 2,
@@ -299,7 +396,7 @@
 
 void
 _cairo_gl_context_destroy_operand (cairo_gl_context_t *ctx,
-                                   cairo_gl_tex_t tex_unit)
+				   cairo_gl_tex_t tex_unit)
 {
     cairo_gl_dispatch_t *dispatch = &ctx->dispatch;
 
@@ -309,21 +406,21 @@
     switch (ctx->operands[tex_unit].type) {
     default:
     case CAIRO_GL_OPERAND_COUNT:
-        ASSERT_NOT_REACHED;
+	ASSERT_NOT_REACHED;
     case CAIRO_GL_OPERAND_NONE:
-        break;
-        /* fall through */
+	break;
+	/* fall through */
     case CAIRO_GL_OPERAND_CONSTANT:
-        break;
+	break;
     case CAIRO_GL_OPERAND_TEXTURE:
-        dispatch->DisableVertexAttribArray (CAIRO_GL_TEXCOORD0_ATTRIB_INDEX + tex_unit);
-        break;
+	dispatch->DisableVertexAttribArray (CAIRO_GL_TEXCOORD0_ATTRIB_INDEX + tex_unit);
+	break;
     case CAIRO_GL_OPERAND_LINEAR_GRADIENT:
     case CAIRO_GL_OPERAND_RADIAL_GRADIENT_A0:
     case CAIRO_GL_OPERAND_RADIAL_GRADIENT_NONE:
     case CAIRO_GL_OPERAND_RADIAL_GRADIENT_EXT:
-        dispatch->DisableVertexAttribArray (CAIRO_GL_TEXCOORD0_ATTRIB_INDEX + tex_unit);
-        break;
+	dispatch->DisableVertexAttribArray (CAIRO_GL_TEXCOORD0_ATTRIB_INDEX + tex_unit);
+	break;
     }
 
     memset (&ctx->operands[tex_unit], 0, sizeof (cairo_gl_operand_t));
@@ -331,7 +428,7 @@
 
 static void
 _cairo_gl_set_operator (cairo_gl_context_t *ctx,
-                        cairo_operator_t    op,
+			cairo_operator_t    op,
 			cairo_bool_t        component_alpha)
 {
     struct {
@@ -359,7 +456,7 @@
     assert (op < ARRAY_LENGTH (blend_factors));
     /* different dst and component_alpha changes cause flushes elsewhere */
     if (ctx->current_operator != op)
-        _cairo_gl_composite_flush (ctx);
+	_cairo_gl_composite_flush (ctx);
     ctx->current_operator = op;
 
     src_factor = blend_factors[op].src;
@@ -384,23 +481,23 @@
     }
 
     if (ctx->current_target->base.content == CAIRO_CONTENT_ALPHA) {
-        glBlendFuncSeparate (GL_ZERO, GL_ZERO, src_factor, dst_factor);
+	glBlendFuncSeparate (GL_ZERO, GL_ZERO, src_factor, dst_factor);
     } else if (ctx->current_target->base.content == CAIRO_CONTENT_COLOR) {
-        glBlendFuncSeparate (src_factor, dst_factor, GL_ONE, GL_ONE);
+	glBlendFuncSeparate (src_factor, dst_factor, GL_ONE, GL_ONE);
     } else {
-        glBlendFunc (src_factor, dst_factor);
+	glBlendFunc (src_factor, dst_factor);
     }
 }
 
 static cairo_status_t
 _cairo_gl_composite_begin_component_alpha  (cairo_gl_context_t *ctx,
-                                            cairo_gl_composite_t *setup)
+					    cairo_gl_composite_t *setup)
 {
     cairo_gl_shader_t *pre_shader = NULL;
     cairo_status_t status;
 
     /* For CLEAR, cairo's rendering equation (quoting Owen's description in:
-     * http://lists.cairographics.org/archives/cairo/2005-August/004992.html)
+     * https://lists.cairographics.org/archives/cairo/2005-August/004992.html)
      * is:
      *     mask IN clip ? src OP dest : dest
      * or more simply:
@@ -420,7 +517,7 @@
      *    mask IN clip ? 0 : dest
      */
     if (setup->op == CAIRO_OPERATOR_CLEAR) {
-        _cairo_gl_solid_operand_init (&setup->src, CAIRO_COLOR_WHITE);
+	_cairo_gl_solid_operand_init (&setup->src, CAIRO_COLOR_WHITE);
 	setup->op = CAIRO_OPERATOR_DEST_OUT;
     }
 
@@ -477,17 +574,17 @@
     if (setup->op == CAIRO_OPERATOR_OVER) {
 	setup->op = CAIRO_OPERATOR_ADD;
 	status = _cairo_gl_get_shader_by_type (ctx,
-                                               &setup->src,
-                                               &setup->mask,
+					       &setup->src,
+					       &setup->mask,
 					       setup->spans,
-                                               CAIRO_GL_SHADER_IN_CA_SOURCE_ALPHA,
-                                               &pre_shader);
-        if (unlikely (status))
-            return status;
+					       CAIRO_GL_SHADER_IN_CA_SOURCE_ALPHA,
+					       &pre_shader);
+	if (unlikely (status))
+	    return status;
     }
 
     if (ctx->pre_shader != pre_shader)
-        _cairo_gl_composite_flush (ctx);
+	_cairo_gl_composite_flush (ctx);
     ctx->pre_shader = pre_shader;
 
     return CAIRO_STATUS_SUCCESS;
@@ -661,7 +758,7 @@
 
     if (setup->clip)
 	return _cairo_gl_composite_setup_painted_clipping (setup, ctx,
-                                                           vertex_size);
+							   vertex_size);
 disable_all_clipping:
     _disable_stencil_buffer ();
     glDisable (GL_SCISSOR_TEST);
@@ -701,13 +798,13 @@
 					   component_alpha ?
 					   CAIRO_GL_SHADER_IN_CA_SOURCE :
 					   CAIRO_GL_SHADER_IN_NORMAL,
-                                           &shader);
+					   &shader);
     if (unlikely (status)) {
 	ctx->pre_shader = NULL;
 	return status;
     }
     if (ctx->current_shader != shader)
-        _cairo_gl_composite_flush (ctx);
+	_cairo_gl_composite_flush (ctx);
 
     status = CAIRO_STATUS_SUCCESS;
 
@@ -769,7 +866,7 @@
 
 FAIL:
     if (unlikely (status))
-        status = _cairo_gl_context_release (ctx, status);
+	status = _cairo_gl_context_release (ctx, status);
 
     return status;
 }
@@ -800,17 +897,17 @@
 				    unsigned int count)
 {
     if (! ctx->pre_shader) {
-        glDrawArrays (GL_TRIANGLES, 0, count);
+	glDrawArrays (GL_TRIANGLES, 0, count);
     } else {
-        cairo_gl_shader_t *prev_shader = ctx->current_shader;
+	cairo_gl_shader_t *prev_shader = ctx->current_shader;
 
-        _cairo_gl_set_shader (ctx, ctx->pre_shader);
-        _cairo_gl_set_operator (ctx, CAIRO_OPERATOR_DEST_OUT, TRUE);
-        glDrawArrays (GL_TRIANGLES, 0, count);
+	_cairo_gl_set_shader (ctx, ctx->pre_shader);
+	_cairo_gl_set_operator (ctx, CAIRO_OPERATOR_DEST_OUT, TRUE);
+	glDrawArrays (GL_TRIANGLES, 0, count);
 
-        _cairo_gl_set_shader (ctx, prev_shader);
-        _cairo_gl_set_operator (ctx, CAIRO_OPERATOR_ADD, TRUE);
-        glDrawArrays (GL_TRIANGLES, 0, count);
+	_cairo_gl_set_shader (ctx, prev_shader);
+	_cairo_gl_set_operator (ctx, CAIRO_OPERATOR_ADD, TRUE);
+	glDrawArrays (GL_TRIANGLES, 0, count);
     }
 }
 
@@ -849,7 +946,7 @@
     int i;
 
     if (_cairo_gl_context_is_flushed (ctx))
-        return;
+	return;
 
     count = ctx->vb_offset / ctx->vertex_size;
     _cairo_gl_composite_unmap_vertex_buffer (ctx);
@@ -931,8 +1028,8 @@
 
 static void
 _cairo_gl_composite_emit_rect (cairo_gl_context_t *ctx,
-                               GLfloat x1, GLfloat y1,
-                               GLfloat x2, GLfloat y2)
+			       GLfloat x1, GLfloat y1,
+			       GLfloat x2, GLfloat y2)
 {
     _cairo_gl_composite_prepare_buffer (ctx, 6,
 					CAIRO_GL_PRIMITIVE_TYPE_TRIANGLES);
@@ -962,9 +1059,9 @@
 
 static void
 _cairo_gl_composite_emit_span (cairo_gl_context_t *ctx,
-                               GLfloat x1, GLfloat y1,
-                               GLfloat x2, GLfloat y2,
-                               uint8_t alpha)
+			       GLfloat x1, GLfloat y1,
+			       GLfloat x2, GLfloat y2,
+			       uint8_t alpha)
 {
     _cairo_gl_composite_prepare_buffer (ctx, 6,
 					CAIRO_GL_PRIMITIVE_TYPE_TRIANGLES);
@@ -1038,7 +1135,7 @@
     switch (ctx->operands[CAIRO_GL_TEX_SOURCE].type) {
     default:
     case CAIRO_GL_OPERAND_COUNT:
-        ASSERT_NOT_REACHED;
+	ASSERT_NOT_REACHED;
     case CAIRO_GL_OPERAND_NONE:
     case CAIRO_GL_OPERAND_CONSTANT:
 	break;
@@ -1079,10 +1176,10 @@
 
 static void
 _cairo_gl_composite_emit_glyph (cairo_gl_context_t *ctx,
-                                GLfloat x1, GLfloat y1,
-                                GLfloat x2, GLfloat y2,
-                                GLfloat glyph_x1, GLfloat glyph_y1,
-                                GLfloat glyph_x2, GLfloat glyph_y2)
+				GLfloat x1, GLfloat y1,
+				GLfloat x2, GLfloat y2,
+				GLfloat glyph_x1, GLfloat glyph_y1,
+				GLfloat glyph_x2, GLfloat glyph_y2)
 {
     _cairo_gl_composite_prepare_buffer (ctx, 6,
 					CAIRO_GL_PRIMITIVE_TYPE_TRIANGLES);
@@ -1130,7 +1227,7 @@
     switch (ctx->operands[CAIRO_GL_TEX_SOURCE].type) {
     default:
     case CAIRO_GL_OPERAND_COUNT:
-        ASSERT_NOT_REACHED;
+	ASSERT_NOT_REACHED;
     case CAIRO_GL_OPERAND_NONE:
     case CAIRO_GL_OPERAND_CONSTANT:
 	return _cairo_gl_composite_emit_solid_glyph;
@@ -1157,13 +1254,13 @@
 				  cairo_bool_t assume_component_alpha)
 {
     if (assume_component_alpha) {
-        if (op != CAIRO_OPERATOR_CLEAR &&
-            op != CAIRO_OPERATOR_OVER &&
-            op != CAIRO_OPERATOR_ADD)
-            return UNSUPPORTED ("unsupported component alpha operator");
+	if (op != CAIRO_OPERATOR_CLEAR &&
+	    op != CAIRO_OPERATOR_OVER &&
+	    op != CAIRO_OPERATOR_ADD)
+	    return UNSUPPORTED ("unsupported component alpha operator");
     } else {
-        if (! _cairo_gl_operator_is_supported (op))
-            return UNSUPPORTED ("unsupported operator");
+	if (! _cairo_gl_operator_is_supported (op))
+	    return UNSUPPORTED ("unsupported operator");
     }
 
     setup->op = op;
@@ -1172,12 +1269,14 @@
 
 cairo_status_t
 _cairo_gl_composite_init (cairo_gl_composite_t *setup,
-                          cairo_operator_t op,
-                          cairo_gl_surface_t *dst,
-                          cairo_bool_t assume_component_alpha)
+			  cairo_operator_t op,
+			  cairo_gl_surface_t *dst,
+			  cairo_bool_t assume_component_alpha)
 {
     cairo_status_t status;
 
+    status = _blit_texture_to_renderbuffer (dst);
+
     memset (setup, 0, sizeof (cairo_gl_composite_t));
 
     status = _cairo_gl_composite_set_operator (setup, op,

Modified: trunk/Build/source/libs/cairo/cairo-src/src/cairo-gl-device.c
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/src/cairo-gl-device.c	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/src/cairo-gl-device.c	2018-10-20 03:19:36 UTC (rev 48952)
@@ -71,7 +71,7 @@
 
     status = _cairo_gl_context_acquire (device, &ctx);
     if (unlikely (status))
-        return status;
+	return status;
 
     _cairo_gl_composite_flush (ctx);
 
@@ -79,8 +79,8 @@
     _cairo_gl_context_destroy_operand (ctx, CAIRO_GL_TEX_MASK);
 
     if (ctx->clip_region) {
-        cairo_region_destroy (ctx->clip_region);
-        ctx->clip_region = NULL;
+	cairo_region_destroy (ctx->clip_region);
+	ctx->clip_region = NULL;
     }
 
     ctx->current_target = NULL;
@@ -171,7 +171,8 @@
     if (gl_flavor == CAIRO_GL_FLAVOR_DESKTOP)
 	return TRUE;
 
-    assert (gl_flavor == CAIRO_GL_FLAVOR_ES);
+    assert (gl_flavor == CAIRO_GL_FLAVOR_ES3 ||
+	    gl_flavor == CAIRO_GL_FLAVOR_ES2);
 
    /* For OpenGL ES we have to look for the specific extension and BGRA only
     * matches cairo's integer packed bytes on little-endian machines. */
@@ -190,7 +191,8 @@
     int n;
 
     cairo_bool_t is_desktop = gl_flavor == CAIRO_GL_FLAVOR_DESKTOP;
-    cairo_bool_t is_gles = gl_flavor == CAIRO_GL_FLAVOR_ES;
+    cairo_bool_t is_gles = (gl_flavor == CAIRO_GL_FLAVOR_ES3 ||
+			    gl_flavor == CAIRO_GL_FLAVOR_ES2);
 
     _cairo_device_init (&ctx->base, &_cairo_gl_device_backend);
 
@@ -263,14 +265,17 @@
     }
 #endif
 
-#if CAIRO_HAS_GLESV2_SURFACE && defined(GL_MAX_SAMPLES_EXT)
+#if CAIRO_HAS_GLESV3_SURFACE
+    if (is_gles && ctx->has_packed_depth_stencil) {
+	glGetIntegerv(GL_MAX_SAMPLES, &ctx->num_samples);
+    }
+
+#elif CAIRO_HAS_GLESV2_SURFACE && defined(GL_MAX_SAMPLES_EXT)
     if (is_gles && ctx->has_packed_depth_stencil &&
 	_cairo_gl_has_extension ("GL_EXT_multisampled_render_to_texture")) {
 	glGetIntegerv(GL_MAX_SAMPLES_EXT, &ctx->num_samples);
     }
-#endif
 
-#if CAIRO_HAS_GLESV2_SURFACE && defined(GL_MAX_SAMPLES_IMG)
     if (is_gles && ctx->has_packed_depth_stencil &&
 	_cairo_gl_has_extension ("GL_IMG_multisampled_render_to_texture")) {
 	glGetIntegerv(GL_MAX_SAMPLES_IMG, &ctx->num_samples);
@@ -277,29 +282,32 @@
     }
 #endif
 
-    ctx->supports_msaa = ctx->num_samples > 1;
+    /* we always use renderbuffer for rendering in glesv3 */
+    if (ctx->gl_flavor == CAIRO_GL_FLAVOR_ES3)
+	ctx->supports_msaa = TRUE;
+    else
+	ctx->supports_msaa = ctx->num_samples > 1;
     if (ctx->num_samples > MAX_MSAA_SAMPLES)
 	ctx->num_samples = MAX_MSAA_SAMPLES;
 
-
     ctx->current_operator = -1;
     ctx->gl_flavor = gl_flavor;
 
     status = _cairo_gl_context_init_shaders (ctx);
     if (unlikely (status))
-        return status;
+	return status;
 
     status = _cairo_cache_init (&ctx->gradients,
-                                _cairo_gl_gradient_equal,
-                                NULL,
-                                (cairo_destroy_func_t) _cairo_gl_gradient_destroy,
-                                CAIRO_GL_GRADIENT_CACHE_SIZE);
+				_cairo_gl_gradient_equal,
+				NULL,
+				(cairo_destroy_func_t) _cairo_gl_gradient_destroy,
+				CAIRO_GL_GRADIENT_CACHE_SIZE);
     if (unlikely (status))
-        return status;
+	return status;
 
     ctx->vbo_size = _cairo_gl_get_vbo_size();
 
-    ctx->vb = malloc (ctx->vbo_size);
+    ctx->vb = _cairo_malloc (ctx->vbo_size);
     if (unlikely (ctx->vb == NULL)) {
 	    _cairo_cache_fini (&ctx->gradients);
 	    return _cairo_error (CAIRO_STATUS_NO_MEMORY);
@@ -326,16 +334,16 @@
 
 void
 _cairo_gl_context_activate (cairo_gl_context_t *ctx,
-                            cairo_gl_tex_t      tex_unit)
+			    cairo_gl_tex_t      tex_unit)
 {
     if (ctx->max_textures <= (GLint) tex_unit) {
-        if (tex_unit < 2) {
-            _cairo_gl_composite_flush (ctx);
-            _cairo_gl_context_destroy_operand (ctx, ctx->max_textures - 1);
-        }
-        glActiveTexture (ctx->max_textures - 1);
+	if (tex_unit < 2) {
+	    _cairo_gl_composite_flush (ctx);
+	    _cairo_gl_context_destroy_operand (ctx, ctx->max_textures - 1);
+	}
+	glActiveTexture (ctx->max_textures - 1);
     } else {
-        glActiveTexture (GL_TEXTURE0 + tex_unit);
+	glActiveTexture (GL_TEXTURE0 + tex_unit);
     }
 }
 
@@ -349,7 +357,7 @@
 	return GL_DEPTH_STENCIL;
 #endif
 
-#if CAIRO_HAS_GLESV2_SURFACE
+#if CAIRO_HAS_GLESV2_SURFACE && !CAIRO_HAS_GLESV3_SURFACE
     if (ctx->gl_flavor == CAIRO_GL_FLAVOR_DESKTOP)
 	return GL_DEPTH24_STENCIL8_OES;
 #endif
@@ -356,6 +364,8 @@
 
 #if CAIRO_HAS_GL_SURFACE
     return GL_DEPTH_STENCIL;
+#elif CAIRO_HAS_GLESV3_SURFACE
+    return GL_DEPTH24_STENCIL8;
 #elif CAIRO_HAS_GLESV2_SURFACE
     return GL_DEPTH24_STENCIL8_OES;
 #endif
@@ -381,15 +391,15 @@
 }
 #endif
 
-static void
+void
 _cairo_gl_ensure_framebuffer (cairo_gl_context_t *ctx,
-                              cairo_gl_surface_t *surface)
+			      cairo_gl_surface_t *surface)
 {
     GLenum status;
     cairo_gl_dispatch_t *dispatch = &ctx->dispatch;
 
     if (likely (surface->fb))
-        return;
+	return;
 
     /* Create a framebuffer object wrapping the texture so that we can render
      * to it.
@@ -402,7 +412,7 @@
        does not require an explicit multisample resolution. */
 #if CAIRO_HAS_GLESV2_SURFACE
     if (surface->supports_msaa && _cairo_gl_msaa_compositor_enabled () &&
-	ctx->gl_flavor == CAIRO_GL_FLAVOR_ES) {
+	ctx->gl_flavor == CAIRO_GL_FLAVOR_ES2) {
 	_cairo_gl_ensure_msaa_gles_framebuffer (ctx, surface);
     } else
 #endif
@@ -436,13 +446,14 @@
 		 str, status);
     }
 }
-#if CAIRO_HAS_GL_SURFACE
+#if CAIRO_HAS_GL_SURFACE || CAIRO_HAS_GLESV3_SURFACE
 static void
 _cairo_gl_ensure_multisampling (cairo_gl_context_t *ctx,
 				cairo_gl_surface_t *surface)
 {
     assert (surface->supports_msaa);
-    assert (ctx->gl_flavor == CAIRO_GL_FLAVOR_DESKTOP);
+    assert (ctx->gl_flavor == CAIRO_GL_FLAVOR_DESKTOP ||
+	ctx->gl_flavor == CAIRO_GL_FLAVOR_ES3);
 
     if (surface->msaa_fb)
 	return;
@@ -460,7 +471,11 @@
        this information. */
     ctx->dispatch.RenderbufferStorageMultisample (GL_RENDERBUFFER,
 						  ctx->num_samples,
+#if CAIRO_HAS_GLESV3_SURFACE
+						  GL_RGBA8,
+#else
 						  GL_RGBA,
+#endif
 						  surface->width,
 						  surface->height);
     ctx->dispatch.FramebufferRenderbuffer (GL_FRAMEBUFFER,
@@ -472,6 +487,11 @@
     glDisable (GL_SCISSOR_TEST);
     glClearColor (0, 0, 0, 0);
     glClear (GL_COLOR_BUFFER_BIT);
+
+    /* for glesv3 with multisample renderbuffer, we always render to
+       this renderbuffer */
+    if (ctx->gl_flavor == CAIRO_GL_FLAVOR_ES3)
+	surface->msaa_active = TRUE;
 }
 #endif
 
@@ -484,14 +504,15 @@
 	return TRUE;
 
     _cairo_gl_ensure_framebuffer (ctx, surface);
-#if CAIRO_HAS_GL_SURFACE
-    if (ctx->gl_flavor == CAIRO_GL_FLAVOR_DESKTOP)
+#if CAIRO_HAS_GL_SURFACE || CAIRO_HAS_GLESV3_SURFACE
+    if (ctx->gl_flavor == CAIRO_GL_FLAVOR_DESKTOP ||
+	ctx->gl_flavor == CAIRO_GL_FLAVOR_ES3)
 	_cairo_gl_ensure_multisampling (ctx, surface);
 #endif
 
     dispatch->GenRenderbuffers (1, &surface->msaa_depth_stencil);
     dispatch->BindRenderbuffer (GL_RENDERBUFFER,
-			        surface->msaa_depth_stencil);
+				surface->msaa_depth_stencil);
 
     dispatch->RenderbufferStorageMultisample (GL_RENDERBUFFER,
 					      ctx->num_samples,
@@ -499,8 +520,9 @@
 					      surface->width,
 					      surface->height);
 
-#if CAIRO_HAS_GL_SURFACE
-    if (ctx->gl_flavor == CAIRO_GL_FLAVOR_DESKTOP) {
+#if CAIRO_HAS_GL_SURFACE || CAIRO_HAS_GLESV3_SURFACE
+    if (ctx->gl_flavor == CAIRO_GL_FLAVOR_DESKTOP ||
+	ctx->gl_flavor == CAIRO_GL_FLAVOR_ES3) {
 	dispatch->FramebufferRenderbuffer (GL_FRAMEBUFFER,
 					   GL_DEPTH_STENCIL_ATTACHMENT,
 					   GL_RENDERBUFFER,
@@ -509,7 +531,7 @@
 #endif
 
 #if CAIRO_HAS_GLESV2_SURFACE
-    if (ctx->gl_flavor == CAIRO_GL_FLAVOR_ES) {
+    if (ctx->gl_flavor == CAIRO_GL_FLAVOR_ES2) {
 	dispatch->FramebufferRenderbuffer (GL_FRAMEBUFFER,
 					   GL_DEPTH_ATTACHMENT,
 					   GL_RENDERBUFFER,
@@ -615,7 +637,7 @@
 #undef M
 }
 
-#if CAIRO_HAS_GL_SURFACE
+#if CAIRO_HAS_GL_SURFACE || CAIRO_HAS_GLESV3_SURFACE
 static void
 bind_multisample_framebuffer (cairo_gl_context_t *ctx,
 			       cairo_gl_surface_t *surface)
@@ -624,14 +646,19 @@
     cairo_bool_t scissor_test_enabled;
 
     assert (surface->supports_msaa);
-    assert (ctx->gl_flavor == CAIRO_GL_FLAVOR_DESKTOP);
+    assert (ctx->gl_flavor == CAIRO_GL_FLAVOR_DESKTOP ||
+	ctx->gl_flavor == CAIRO_GL_FLAVOR_ES3);
 
     _cairo_gl_ensure_framebuffer (ctx, surface);
     _cairo_gl_ensure_multisampling (ctx, surface);
 
     if (surface->msaa_active) {
+#if CAIRO_HAS_GL_SURFACE
 	glEnable (GL_MULTISAMPLE);
+#endif
 	ctx->dispatch.BindFramebuffer (GL_FRAMEBUFFER, surface->msaa_fb);
+	if (ctx->gl_flavor == CAIRO_GL_FLAVOR_ES3)
+	    surface->content_in_texture = FALSE;
 	return;
     }
 
@@ -642,7 +669,9 @@
     glDisable (GL_STENCIL_TEST);
     glDisable (GL_SCISSOR_TEST);
 
+#if CAIRO_HAS_GL_SURFACE
     glEnable (GL_MULTISAMPLE);
+#endif
 
     /* The last time we drew to the surface, we were not using multisampling,
        so we need to blit from the non-multisampling framebuffer into the
@@ -651,7 +680,12 @@
     ctx->dispatch.BindFramebuffer (GL_READ_FRAMEBUFFER, surface->fb);
     ctx->dispatch.BlitFramebuffer (0, 0, surface->width, surface->height,
 				   0, 0, surface->width, surface->height,
-				   GL_COLOR_BUFFER_BIT, GL_NEAREST);
+				   GL_COLOR_BUFFER_BIT
+#if CAIRO_HAS_GL_SURFACE
+				   | GL_STENCIL_BUFFER_BIT
+#endif
+				   ,
+				   GL_NEAREST);
     ctx->dispatch.BindFramebuffer (GL_FRAMEBUFFER, surface->msaa_fb);
 
     if (stencil_test_enabled)
@@ -658,10 +692,12 @@
 	glEnable (GL_STENCIL_TEST);
     if (scissor_test_enabled)
 	glEnable (GL_SCISSOR_TEST);
+    if (ctx->gl_flavor == CAIRO_GL_FLAVOR_ES3)
+	surface->content_in_texture = FALSE;
 }
 #endif
 
-#if CAIRO_HAS_GL_SURFACE
+#if CAIRO_HAS_GL_SURFACE || CAIRO_HAS_GLESV3_SURFACE
 static void
 bind_singlesample_framebuffer (cairo_gl_context_t *ctx,
 			       cairo_gl_surface_t *surface)
@@ -669,11 +705,15 @@
     cairo_bool_t stencil_test_enabled;
     cairo_bool_t scissor_test_enabled;
 
-    assert (ctx->gl_flavor == CAIRO_GL_FLAVOR_DESKTOP);
+    assert (ctx->gl_flavor == CAIRO_GL_FLAVOR_DESKTOP ||
+	ctx->gl_flavor == CAIRO_GL_FLAVOR_ES3);
     _cairo_gl_ensure_framebuffer (ctx, surface);
 
     if (! surface->msaa_active) {
+#if CAIRO_HAS_GL_SURFACE
 	glDisable (GL_MULTISAMPLE);
+#endif
+
 	ctx->dispatch.BindFramebuffer (GL_FRAMEBUFFER, surface->fb);
 	return;
     }
@@ -685,7 +725,9 @@
     glDisable (GL_STENCIL_TEST);
     glDisable (GL_SCISSOR_TEST);
 
+#if CAIRO_HAS_GL_SURFACE
     glDisable (GL_MULTISAMPLE);
+#endif
 
     /* The last time we drew to the surface, we were using multisampling,
        so we need to blit from the multisampling framebuffer into the
@@ -712,13 +754,13 @@
     if (_cairo_gl_surface_is_texture (surface)) {
 	/* OpenGL ES surfaces only have either a multisample framebuffer or a
 	 * singlesample framebuffer, so we cannot switch back and forth. */
-	if (ctx->gl_flavor == CAIRO_GL_FLAVOR_ES) {
+	if (ctx->gl_flavor == CAIRO_GL_FLAVOR_ES2) {
 	    _cairo_gl_ensure_framebuffer (ctx, surface);
 	    ctx->dispatch.BindFramebuffer (GL_FRAMEBUFFER, surface->fb);
 	    return;
 	}
 
-#if CAIRO_HAS_GL_SURFACE
+#if CAIRO_HAS_GL_SURFACE || CAIRO_HAS_GLESV3_SURFACE
 	if (multisampling)
 	    bind_multisample_framebuffer (ctx, surface);
 	else
@@ -737,23 +779,28 @@
 #endif
     }
 
-    surface->msaa_active = multisampling;
+    if (ctx->gl_flavor == CAIRO_GL_FLAVOR_DESKTOP)
+	surface->msaa_active = multisampling;
 }
 
 void
 _cairo_gl_context_set_destination (cairo_gl_context_t *ctx,
-                                   cairo_gl_surface_t *surface,
-                                   cairo_bool_t multisampling)
+				   cairo_gl_surface_t *surface,
+				   cairo_bool_t multisampling)
 {
     cairo_bool_t changing_surface, changing_sampling;
 
     /* The decision whether or not to use multisampling happens when
      * we create an OpenGL ES surface, so we can never switch modes. */
-    if (ctx->gl_flavor == CAIRO_GL_FLAVOR_ES)
+    if (ctx->gl_flavor == CAIRO_GL_FLAVOR_ES2)
 	multisampling = surface->msaa_active;
+    /* For GLESV3, we always use renderbuffer for drawing */
+    else if (ctx->gl_flavor == CAIRO_GL_FLAVOR_ES3)
+	multisampling = TRUE;
 
     changing_surface = ctx->current_target != surface || surface->needs_update;
-    changing_sampling = surface->msaa_active != multisampling;
+    changing_sampling = (surface->msaa_active != multisampling ||
+			 surface->content_in_texture);
     if (! changing_surface && ! changing_sampling)
 	return;
 

Modified: trunk/Build/source/libs/cairo/cairo-src/src/cairo-gl-dispatch.c
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/src/cairo-gl-dispatch.c	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/src/cairo-gl-dispatch.c	2018-10-20 03:19:36 UTC (rev 48952)
@@ -124,7 +124,11 @@
 	else
 	    return CAIRO_STATUS_DEVICE_ERROR;
     }
-    else if (gl_flavor == CAIRO_GL_FLAVOR_ES &&
+    else if (gl_flavor == CAIRO_GL_FLAVOR_ES3)
+    {
+	dispatch_name = CAIRO_GL_DISPATCH_NAME_CORE;
+    }
+    else if (gl_flavor == CAIRO_GL_FLAVOR_ES2 &&
 	     gl_version >= CAIRO_GL_VERSION_ENCODE (2, 0))
     {
 	dispatch_name = CAIRO_GL_DISPATCH_NAME_ES;
@@ -156,7 +160,11 @@
 	else
 	    return CAIRO_STATUS_DEVICE_ERROR;
     }
-    else if (gl_flavor == CAIRO_GL_FLAVOR_ES &&
+    else if (gl_flavor == CAIRO_GL_FLAVOR_ES3)
+    {
+	dispatch_name = CAIRO_GL_DISPATCH_NAME_CORE;
+    }
+    else if (gl_flavor == CAIRO_GL_FLAVOR_ES2 &&
 	     gl_version >= CAIRO_GL_VERSION_ENCODE (2, 0))
     {
 	dispatch_name = CAIRO_GL_DISPATCH_NAME_ES;
@@ -189,7 +197,11 @@
 	else
 	    return CAIRO_STATUS_DEVICE_ERROR;
     }
-    else if (gl_flavor == CAIRO_GL_FLAVOR_ES &&
+    else if (gl_flavor == CAIRO_GL_FLAVOR_ES3)
+    {
+	dispatch_name = CAIRO_GL_DISPATCH_NAME_CORE;
+    }
+    else if (gl_flavor == CAIRO_GL_FLAVOR_ES2 &&
 	     gl_version >= CAIRO_GL_VERSION_ENCODE (2, 0))
     {
 	dispatch_name = CAIRO_GL_DISPATCH_NAME_ES;
@@ -214,7 +226,7 @@
     /* For the multisampling table, there are two GLES versions of the
      * extension, so we put one in the EXT slot and one in the real ES slot.*/
     cairo_gl_dispatch_name_t dispatch_name = CAIRO_GL_DISPATCH_NAME_CORE;
-    if (gl_flavor == CAIRO_GL_FLAVOR_ES) {
+    if (gl_flavor == CAIRO_GL_FLAVOR_ES2) {
 	if (_cairo_gl_has_extension ("GL_EXT_multisampled_render_to_texture"))
 	    dispatch_name = CAIRO_GL_DISPATCH_NAME_EXT;
 	else if (_cairo_gl_has_extension ("GL_IMG_multisampled_render_to_texture"))

Modified: trunk/Build/source/libs/cairo/cairo-src/src/cairo-gl-glyphs.c
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/src/cairo-gl-glyphs.c	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/src/cairo-gl-glyphs.c	2018-10-20 03:19:36 UTC (rev 48952)
@@ -120,10 +120,10 @@
     /* search for an unlocked slot */
     if (status == CAIRO_INT_STATUS_UNSUPPORTED) {
 	status = _cairo_rtree_evict_random (&cache->rtree,
-				            width, height, &node);
+					    width, height, &node);
 	if (status == CAIRO_INT_STATUS_SUCCESS) {
 	    status = _cairo_rtree_node_insert (&cache->rtree,
-		                               node, width, height, &node);
+					       node, width, height, &node);
 	}
     }
     if (status)
@@ -132,9 +132,9 @@
     /* XXX: Make sure we use the mask texture. This should work automagically somehow */
     glActiveTexture (GL_TEXTURE1);
     status = _cairo_gl_surface_draw_image (cache->surface, glyph_surface,
-                                           0, 0,
-                                           glyph_surface->width, glyph_surface->height,
-                                           node->x, node->y, FALSE);
+					   0, 0,
+					   glyph_surface->width, glyph_surface->height,
+					   node->x, node->y, FALSE);
     if (unlikely (status))
 	return status;
 
@@ -174,7 +174,7 @@
 static cairo_status_t
 cairo_gl_context_get_glyph_cache (cairo_gl_context_t *ctx,
 				  cairo_format_t format,
-                                  cairo_gl_glyph_cache_t **cache_out)
+				  cairo_gl_glyph_cache_t **cache_out)
 {
     cairo_gl_glyph_cache_t *cache;
     cairo_content_t content;
@@ -185,12 +185,12 @@
     case CAIRO_FORMAT_ARGB32:
     case CAIRO_FORMAT_RGB24:
 	cache = &ctx->glyph_cache[0];
-        content = CAIRO_CONTENT_COLOR_ALPHA;
+	content = CAIRO_CONTENT_COLOR_ALPHA;
 	break;
     case CAIRO_FORMAT_A8:
     case CAIRO_FORMAT_A1:
 	cache = &ctx->glyph_cache[1];
-        content = CAIRO_CONTENT_ALPHA;
+	content = CAIRO_CONTENT_ALPHA;
 	break;
     default:
     case CAIRO_FORMAT_INVALID:
@@ -202,9 +202,9 @@
 	cairo_surface_t *surface;
 
 	surface = _cairo_gl_surface_create_scratch_for_caching (ctx,
-							        content,
-							        GLYPH_CACHE_WIDTH,
-							        GLYPH_CACHE_HEIGHT);
+								content,
+								GLYPH_CACHE_WIDTH,
+								GLYPH_CACHE_HEIGHT);
 	if (unlikely (surface->status))
 	    return surface->status;
 
@@ -281,9 +281,9 @@
 	if (scaled_glyph->surface->format != last_format) {
 	    status = cairo_gl_context_get_glyph_cache (ctx,
 						       scaled_glyph->surface->format,
-                                                       &cache);
-            if (unlikely (status))
-                goto FINISH;
+						       &cache);
+	    if (unlikely (status))
+		goto FINISH;
 
 	    last_format = scaled_glyph->surface->format;
 
@@ -291,8 +291,8 @@
 	    *has_component_alpha |= cache->surface->operand.texture.attributes.has_component_alpha;
 
 	    /* XXX Shoot me. */
-            status = _cairo_gl_composite_begin (&setup, &ctx);
-            status = _cairo_gl_context_release (ctx, status);
+	    status = _cairo_gl_composite_begin (&setup, &ctx);
+	    status = _cairo_gl_context_release (ctx, status);
 	    if (unlikely (status))
 		goto FINISH;
 
@@ -363,11 +363,11 @@
 
     /* XXX: For non-CA, this should be CAIRO_CONTENT_ALPHA to save memory */
     mask = cairo_gl_surface_create (dst->base.device,
-                                    CAIRO_CONTENT_COLOR_ALPHA,
-                                    info->extents.width,
-                                    info->extents.height);
+				    CAIRO_CONTENT_COLOR_ALPHA,
+				    info->extents.width,
+				    info->extents.height);
     if (unlikely (mask->status))
-        return mask->status;
+	return mask->status;
 
     status = render_glyphs ((cairo_gl_surface_t *) mask,
 			    info->extents.x, info->extents.y,
@@ -385,11 +385,11 @@
 	mask_pattern.base.extend = CAIRO_EXTEND_NONE;
 
 	cairo_matrix_init_translate (&mask_pattern.base.matrix,
-		                     dst_x-info->extents.x, dst_y-info->extents.y);
+				     dst_x-info->extents.x, dst_y-info->extents.y);
 
 	_cairo_pattern_init_for_surface (&source_pattern, source);
 	cairo_matrix_init_translate (&source_pattern.base.matrix,
-		                     dst_x-info->extents.x, dst_y-info->extents.y);
+				     dst_x-info->extents.x, dst_y-info->extents.y);
 
 	clip = _cairo_clip_copy (clip);
 	clip_extents.x = info->extents.x - dst_x;
@@ -399,7 +399,7 @@
 	clip = _cairo_clip_intersect_rectangle (clip, &clip_extents);
 
 	status = _cairo_surface_mask (&dst->base, op,
-		                      &source_pattern.base,
+				      &source_pattern.base,
 				      &mask_pattern.base,
 				      clip);
 

Modified: trunk/Build/source/libs/cairo/cairo-src/src/cairo-gl-gradient-private.h
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/src/cairo-gl-gradient-private.h	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/src/cairo-gl-gradient-private.h	2018-10-20 03:19:36 UTC (rev 48952)
@@ -51,12 +51,15 @@
 
 #include "cairo-gl.h"
 
-#if CAIRO_HAS_GL_SURFACE
-#include <GL/gl.h>
-#include <GL/glext.h>
+#if CAIRO_HAS_GLESV3_SURFACE
+#include <GLES3/gl3.h>
+#include <GLES3/gl3ext.h>
 #elif CAIRO_HAS_GLESV2_SURFACE
 #include <GLES2/gl2.h>
 #include <GLES2/gl2ext.h>
+#elif CAIRO_HAS_GL_SURFACE
+#include <GL/gl.h>
+#include <GL/glext.h>
 #endif
 
 #define CAIRO_GL_GRADIENT_CACHE_SIZE 4096

Modified: trunk/Build/source/libs/cairo/cairo-src/src/cairo-gl-gradient.c
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/src/cairo-gl-gradient.c	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/src/cairo-gl-gradient.c	2018-10-20 03:19:36 UTC (rev 48952)
@@ -47,7 +47,7 @@
 
 static int
 _cairo_gl_gradient_sample_width (unsigned int                 n_stops,
-                                 const cairo_gradient_stop_t *stops)
+				 const cairo_gradient_stop_t *stops)
 {
     unsigned int n;
     int width;
@@ -106,10 +106,10 @@
 
 static cairo_status_t
 _cairo_gl_gradient_render (const cairo_gl_context_t    *ctx,
-                           unsigned int                 n_stops,
-                           const cairo_gradient_stop_t *stops,
-                           void                        *bytes,
-                           int                          width)
+			   unsigned int                 n_stops,
+			   const cairo_gradient_stop_t *stops,
+			   void                        *bytes,
+			   int                          width)
 {
     pixman_image_t *gradient, *image;
     pixman_gradient_stop_t pixman_stops_stack[32];
@@ -169,11 +169,11 @@
     }
 
     pixman_image_composite32 (PIXMAN_OP_SRC,
-                              gradient, NULL, image,
-                              0, 0,
-                              0, 0,
-                              0, 0,
-                              width, 1);
+			      gradient, NULL, image,
+			      0, 0,
+			      0, 0,
+			      0, 0,
+			      width, 1);
 
     pixman_image_unref (gradient);
     pixman_image_unref (image);
@@ -190,18 +190,18 @@
 
 static unsigned long
 _cairo_gl_gradient_hash (unsigned int                  n_stops,
-                         const cairo_gradient_stop_t  *stops)
+			 const cairo_gradient_stop_t  *stops)
 {
     return _cairo_hash_bytes (n_stops,
-                              stops,
-                              sizeof (cairo_gradient_stop_t) * n_stops);
+			      stops,
+			      sizeof (cairo_gradient_stop_t) * n_stops);
 }
 
 static cairo_gl_gradient_t *
 _cairo_gl_gradient_lookup (cairo_gl_context_t           *ctx,
-                           unsigned long                 hash,
-                           unsigned int                  n_stops,
-                           const cairo_gradient_stop_t  *stops)
+			   unsigned long                 hash,
+			   unsigned int                  n_stops,
+			   const cairo_gradient_stop_t  *stops)
 {
     cairo_gl_gradient_t lookup;
 
@@ -219,7 +219,7 @@
     const cairo_gl_gradient_t *b = key_b;
 
     if (a->n_stops != b->n_stops)
-        return FALSE;
+	return FALSE;
 
     return memcmp (a->stops, b->stops, a->n_stops * sizeof (cairo_gradient_stop_t)) == 0;
 }
@@ -226,9 +226,9 @@
 
 cairo_int_status_t
 _cairo_gl_gradient_create (cairo_gl_context_t           *ctx,
-                           unsigned int                  n_stops,
-                           const cairo_gradient_stop_t  *stops,
-                           cairo_gl_gradient_t         **gradient_out)
+			   unsigned int                  n_stops,
+			   const cairo_gradient_stop_t  *stops,
+			   cairo_gl_gradient_t         **gradient_out)
 {
     unsigned long hash;
     cairo_gl_gradient_t *gradient;
@@ -248,7 +248,7 @@
 	return CAIRO_STATUS_SUCCESS;
     }
 
-    gradient = malloc (sizeof (cairo_gl_gradient_t) + sizeof (cairo_gradient_stop_t) * (n_stops - 1));
+    gradient = _cairo_malloc (sizeof (cairo_gl_gradient_t) + sizeof (cairo_gradient_stop_t) * (n_stops - 1));
     if (gradient == NULL)
 	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
@@ -282,7 +282,8 @@
      * In OpenGL ES 2.0 no format conversion is allowed i.e. 'internalFormat'
      * must match 'format' in glTexImage2D.
      */
-    if (_cairo_gl_get_flavor () == CAIRO_GL_FLAVOR_ES)
+    if (_cairo_gl_get_flavor () == CAIRO_GL_FLAVOR_ES3 ||
+	_cairo_gl_get_flavor () == CAIRO_GL_FLAVOR_ES2)
 	internal_format = GL_BGRA;
     else
 	internal_format = GL_RGBA;
@@ -330,8 +331,8 @@
     if (_cairo_gl_context_acquire (gradient->device, &ctx) == CAIRO_STATUS_SUCCESS) {
 	/* The gradient my still be active in the last operation, so flush */
 	_cairo_gl_composite_flush (ctx);
-        glDeleteTextures (1, &gradient->tex);
-        ignore = _cairo_gl_context_release (ctx, CAIRO_STATUS_SUCCESS);
+	glDeleteTextures (1, &gradient->tex);
+	ignore = _cairo_gl_context_release (ctx, CAIRO_STATUS_SUCCESS);
     }
 
     free (gradient);

Modified: trunk/Build/source/libs/cairo/cairo-src/src/cairo-gl-info.c
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/src/cairo-gl-info.c	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/src/cairo-gl-info.c	2018-10-20 03:19:36 UTC (rev 48952)
@@ -65,8 +65,10 @@
 
     if (version == NULL)
 	flavor = CAIRO_GL_FLAVOR_NONE;
-    else if (strstr (version, "OpenGL ES") != NULL)
-	flavor = CAIRO_GL_FLAVOR_ES;
+    else if (strstr (version, "OpenGL ES 3") != NULL)
+	flavor = CAIRO_GL_FLAVOR_ES3;
+    else if (strstr (version, "OpenGL ES 2") != NULL)
+	flavor = CAIRO_GL_FLAVOR_ES2;
     else
 	flavor = CAIRO_GL_FLAVOR_DESKTOP;
 
@@ -80,7 +82,7 @@
 
     const char *env = getenv ("CAIRO_GL_VBO_SIZE");
     if (env == NULL) {
-        vbo_size = CAIRO_GL_VBO_SIZE_DEFAULT;
+	vbo_size = CAIRO_GL_VBO_SIZE_DEFAULT;
     } else {
 	errno = 0;
 	vbo_size = strtol (env, NULL, 10);

Modified: trunk/Build/source/libs/cairo/cairo-src/src/cairo-gl-msaa-compositor.c
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/src/cairo-gl-msaa-compositor.c	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/src/cairo-gl-msaa-compositor.c	2018-10-20 03:19:36 UTC (rev 48952)
@@ -224,8 +224,8 @@
     /* This isn't just an optimization. It also detects when painting is used
        to paint back the unbounded surface, preventing infinite recursion. */
     return ! (source->x <= 0 && source->y <= 0 &&
-              source->height + source->y >= dst->height &&
-              source->width + source->x >= dst->width);
+	      source->height + source->y >= dst->height &&
+	      source->width + source->x >= dst->width);
 }
 
 static cairo_surface_t*
@@ -237,10 +237,10 @@
 							dst->width,
 							dst->height);
     if (surface == NULL)
-        return NULL;
+	return NULL;
     if (unlikely (surface->status)) {
-        cairo_surface_destroy (surface);
-        return NULL;
+	cairo_surface_destroy (surface);
+	return NULL;
     }
     return surface;
 }
@@ -273,6 +273,8 @@
 can_use_msaa_compositor (cairo_gl_surface_t *surface,
 			 cairo_antialias_t antialias)
 {
+    cairo_gl_flavor_t gl_flavor = ((cairo_gl_context_t *) surface->base.device)->gl_flavor;
+
     query_surface_capabilities (surface);
     if (! surface->supports_stencil)
 	return FALSE;
@@ -280,8 +282,10 @@
     /* Multisampling OpenGL ES surfaces only maintain one multisampling
        framebuffer and thus must use the spans compositor to do non-antialiased
        rendering. */
-    if (((cairo_gl_context_t *) surface->base.device)->gl_flavor == CAIRO_GL_FLAVOR_ES
+    if ((gl_flavor == CAIRO_GL_FLAVOR_ES3 ||
+	 gl_flavor == CAIRO_GL_FLAVOR_ES2)
 	 && surface->supports_msaa
+	 && surface->num_samples > 1
 	 && antialias == CAIRO_ANTIALIAS_NONE)
 	return FALSE;
 
@@ -357,13 +361,13 @@
     else
 	status = _draw_traps (ctx, &setup, &traps);
     if (unlikely (status))
-        goto finish;
+	goto finish;
 
     /* Now draw the second pass. */
     status = _cairo_gl_composite_set_operator (&setup, CAIRO_OPERATOR_ADD,
 					       FALSE /* assume_component_alpha */);
     if (unlikely (status))
-        goto finish;
+	goto finish;
     status = _cairo_gl_composite_set_source (&setup,
 					     &composite->source_pattern.base,
 					     &composite->source_sample_area,
@@ -372,12 +376,15 @@
     if (unlikely (status))
 	goto finish;
     status = _cairo_gl_composite_set_mask (&setup,
-				           &composite->mask_pattern.base,
+					   &composite->mask_pattern.base,
 					   &composite->source_sample_area,
 					   &composite->bounded,
 					   FALSE);
     if (unlikely (status))
 	goto finish;
+
+    _cairo_gl_context_set_destination (ctx, dst, setup.multisample);
+
     status = _cairo_gl_set_operands_and_operator (&setup, ctx);
     if (unlikely (status))
 	goto finish;
@@ -546,9 +553,9 @@
 }
 
 static cairo_int_status_t
-_prevent_overlapping_strokes (cairo_gl_context_t 		*ctx,
-			      cairo_gl_composite_t 		*setup,
-			      cairo_composite_rectangles_t 	*composite,
+_prevent_overlapping_strokes (cairo_gl_context_t		*ctx,
+			      cairo_gl_composite_t		*setup,
+			      cairo_composite_rectangles_t	*composite,
 			      const cairo_path_fixed_t		*path,
 			      const cairo_stroke_style_t	*style,
 			      const cairo_matrix_t		*ctm)
@@ -582,6 +589,7 @@
 	scissor_was_enabled = glIsEnabled (GL_SCISSOR_TEST);
 	if (! scissor_was_enabled) {
 	    _cairo_path_fixed_approximate_stroke_extents (path, style, ctm,
+							  FALSE, /* is_vector */
 							  &stroke_extents);
 	    _cairo_gl_scissor_to_rectangle (setup->dst, &stroke_extents);
 	}
@@ -633,6 +641,7 @@
     glGetIntegerv(GL_STENCIL_BITS, &stencil_bits);
     surface->supports_stencil = stencil_bits > 0;
     surface->supports_msaa = samples > 1;
+    surface->num_samples = samples;
 
     status = _cairo_gl_context_release (ctx, status);
 }
@@ -823,7 +832,7 @@
     else
 	status = _draw_traps (ctx, &setup, &traps);
     if (unlikely (status))
-        goto cleanup_setup;
+	goto cleanup_setup;
 
 cleanup_setup:
     _cairo_gl_composite_fini (&setup);
@@ -935,10 +944,13 @@
 const cairo_compositor_t *
 _cairo_gl_msaa_compositor_get (void)
 {
+    static cairo_atomic_once_t once = CAIRO_ATOMIC_ONCE_INIT;
     static cairo_compositor_t compositor;
-    if (compositor.delegate == NULL)
+    if (_cairo_atomic_init_once_enter(&once)) {
 	_cairo_gl_msaa_compositor_init (&compositor,
 					_cairo_gl_span_compositor_get ());
+	_cairo_atomic_init_once_leave(&once);
+    }
 
     return &compositor;
 }

Modified: trunk/Build/source/libs/cairo/cairo-src/src/cairo-gl-operand.c
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/src/cairo-gl-operand.c	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/src/cairo-gl-operand.c	2018-10-20 03:19:36 UTC (rev 48952)
@@ -55,7 +55,7 @@
 static cairo_int_status_t
 _cairo_gl_create_gradient_texture (cairo_gl_surface_t *dst,
 				   const cairo_gradient_pattern_t *pattern,
-                                   cairo_gl_gradient_t **gradient)
+				   cairo_gl_gradient_t **gradient)
 {
     cairo_gl_context_t *ctx;
     cairo_status_t status;
@@ -130,7 +130,7 @@
 
     status = _cairo_gl_surface_resolve_multisampling (surface);
     if (unlikely (status))
-        return status;
+	return status;
 
     attributes = &operand->texture.attributes;
 
@@ -336,7 +336,7 @@
 
 void
 _cairo_gl_solid_operand_init (cairo_gl_operand_t *operand,
-	                      const cairo_color_t *color)
+			      const cairo_color_t *color)
 {
     operand->type = CAIRO_GL_OPERAND_CONSTANT;
     operand->constant.color[0] = color->red   * color->alpha;
@@ -373,7 +373,7 @@
 
 static cairo_status_t
 _cairo_gl_gradient_operand_init (cairo_gl_operand_t *operand,
-                                 const cairo_pattern_t *pattern,
+				 const cairo_pattern_t *pattern,
 				 cairo_gl_surface_t *dst,
 				 cairo_bool_t use_texgen)
 {
@@ -482,9 +482,9 @@
 	break;
     default:
     case CAIRO_GL_OPERAND_COUNT:
-        ASSERT_NOT_REACHED;
+	ASSERT_NOT_REACHED;
     case CAIRO_GL_OPERAND_NONE:
-        break;
+	break;
     }
 }
 
@@ -505,9 +505,9 @@
 	break;
     default:
     case CAIRO_GL_OPERAND_COUNT:
-        ASSERT_NOT_REACHED;
+	ASSERT_NOT_REACHED;
     case CAIRO_GL_OPERAND_NONE:
-        break;
+	break;
     }
 
     operand->type = CAIRO_GL_OPERAND_NONE;
@@ -515,8 +515,8 @@
 
 cairo_int_status_t
 _cairo_gl_operand_init (cairo_gl_operand_t *operand,
-		        const cairo_pattern_t *pattern,
-		        cairo_gl_surface_t *dst,
+			const cairo_pattern_t *pattern,
+			cairo_gl_surface_t *dst,
 			const cairo_rectangle_int_t *sample,
 			const cairo_rectangle_int_t *extents,
 			cairo_bool_t use_texgen)
@@ -614,8 +614,8 @@
 
 void
 _cairo_gl_operand_bind_to_shader (cairo_gl_context_t *ctx,
-                                  cairo_gl_operand_t *operand,
-                                  cairo_gl_tex_t      tex_unit)
+				  cairo_gl_operand_t *operand,
+				  cairo_gl_tex_t      tex_unit)
 {
     const cairo_matrix_t *texgen = NULL;
 
@@ -622,17 +622,17 @@
     switch (operand->type) {
     default:
     case CAIRO_GL_OPERAND_COUNT:
-        ASSERT_NOT_REACHED;
+	ASSERT_NOT_REACHED;
     case CAIRO_GL_OPERAND_NONE:
 	return;
 
     case CAIRO_GL_OPERAND_CONSTANT:
 	_cairo_gl_shader_bind_vec4 (ctx,
-                                    ctx->current_shader->constant_location[tex_unit],
-                                    operand->constant.color[0],
-                                    operand->constant.color[1],
-                                    operand->constant.color[2],
-                                    operand->constant.color[3]);
+				    ctx->current_shader->constant_location[tex_unit],
+				    operand->constant.color[0],
+				    operand->constant.color[1],
+				    operand->constant.color[2],
+				    operand->constant.color[3]);
 	return;
 
     case CAIRO_GL_OPERAND_RADIAL_GRADIENT_NONE:
@@ -650,7 +650,7 @@
 	_cairo_gl_shader_bind_float  (ctx,
 				      ctx->current_shader->radius_0_location[tex_unit],
 				      operand->gradient.radius_0);
-        /* fall through */
+	/* fall through */
     case CAIRO_GL_OPERAND_LINEAR_GRADIENT:
     case CAIRO_GL_OPERAND_TEXTURE:
 	/*
@@ -658,7 +658,8 @@
 	 * with CAIRO_EXTEND_NONE). When bilinear filtering is enabled,
 	 * these shaders need the texture dimensions for their calculations.
 	 */
-	if (ctx->gl_flavor == CAIRO_GL_FLAVOR_ES &&
+	if ((ctx->gl_flavor == CAIRO_GL_FLAVOR_ES3 ||
+	     ctx->gl_flavor == CAIRO_GL_FLAVOR_ES2) &&
 	    _cairo_gl_operand_get_extend (operand) == CAIRO_EXTEND_NONE &&
 	    _cairo_gl_operand_get_gl_filter (operand) == GL_LINEAR)
 	{
@@ -695,37 +696,37 @@
 
 cairo_bool_t
 _cairo_gl_operand_needs_setup (cairo_gl_operand_t *dest,
-                               cairo_gl_operand_t *source,
-                               unsigned int        vertex_offset)
+			       cairo_gl_operand_t *source,
+			       unsigned int        vertex_offset)
 {
     if (dest->type != source->type)
-        return TRUE;
+	return TRUE;
     if (dest->vertex_offset != vertex_offset)
-        return TRUE;
+	return TRUE;
 
     switch (source->type) {
     case CAIRO_GL_OPERAND_NONE:
-        return FALSE;
+	return FALSE;
     case CAIRO_GL_OPERAND_CONSTANT:
-        return dest->constant.color[0] != source->constant.color[0] ||
-               dest->constant.color[1] != source->constant.color[1] ||
-               dest->constant.color[2] != source->constant.color[2] ||
-               dest->constant.color[3] != source->constant.color[3];
+	return dest->constant.color[0] != source->constant.color[0] ||
+	       dest->constant.color[1] != source->constant.color[1] ||
+	       dest->constant.color[2] != source->constant.color[2] ||
+	       dest->constant.color[3] != source->constant.color[3];
     case CAIRO_GL_OPERAND_TEXTURE:
-        return dest->texture.surface != source->texture.surface ||
-               dest->texture.attributes.extend != source->texture.attributes.extend ||
-               dest->texture.attributes.filter != source->texture.attributes.filter ||
-               dest->texture.attributes.has_component_alpha != source->texture.attributes.has_component_alpha;
+	return dest->texture.surface != source->texture.surface ||
+	       dest->texture.attributes.extend != source->texture.attributes.extend ||
+	       dest->texture.attributes.filter != source->texture.attributes.filter ||
+	       dest->texture.attributes.has_component_alpha != source->texture.attributes.has_component_alpha;
     case CAIRO_GL_OPERAND_LINEAR_GRADIENT:
     case CAIRO_GL_OPERAND_RADIAL_GRADIENT_A0:
     case CAIRO_GL_OPERAND_RADIAL_GRADIENT_NONE:
     case CAIRO_GL_OPERAND_RADIAL_GRADIENT_EXT:
-        /* XXX: improve this */
-        return TRUE;
+	/* XXX: improve this */
+	return TRUE;
     default:
     case CAIRO_GL_OPERAND_COUNT:
-        ASSERT_NOT_REACHED;
-        break;
+	ASSERT_NOT_REACHED;
+	break;
     }
     return TRUE;
 }
@@ -736,33 +737,33 @@
     switch (operand->type) {
     default:
     case CAIRO_GL_OPERAND_COUNT:
-        ASSERT_NOT_REACHED;
+	ASSERT_NOT_REACHED;
     case CAIRO_GL_OPERAND_NONE:
     case CAIRO_GL_OPERAND_CONSTANT:
-        return 0;
+	return 0;
     case CAIRO_GL_OPERAND_TEXTURE:
-        return operand->texture.texgen ? 0 : 2 * sizeof (GLfloat);
+	return operand->texture.texgen ? 0 : 2 * sizeof (GLfloat);
     case CAIRO_GL_OPERAND_LINEAR_GRADIENT:
     case CAIRO_GL_OPERAND_RADIAL_GRADIENT_A0:
     case CAIRO_GL_OPERAND_RADIAL_GRADIENT_NONE:
     case CAIRO_GL_OPERAND_RADIAL_GRADIENT_EXT:
-        return operand->gradient.texgen ? 0 : 2 * sizeof (GLfloat);
+	return operand->gradient.texgen ? 0 : 2 * sizeof (GLfloat);
     }
 }
 
 void
 _cairo_gl_operand_emit (cairo_gl_operand_t *operand,
-                        GLfloat ** vb,
-                        GLfloat x,
-                        GLfloat y)
+			GLfloat ** vb,
+			GLfloat x,
+			GLfloat y)
 {
     switch (operand->type) {
     default:
     case CAIRO_GL_OPERAND_COUNT:
-        ASSERT_NOT_REACHED;
+	ASSERT_NOT_REACHED;
     case CAIRO_GL_OPERAND_NONE:
     case CAIRO_GL_OPERAND_CONSTANT:
-        break;
+	break;
     case CAIRO_GL_OPERAND_LINEAR_GRADIENT:
     case CAIRO_GL_OPERAND_RADIAL_GRADIENT_A0:
     case CAIRO_GL_OPERAND_RADIAL_GRADIENT_NONE:
@@ -775,18 +776,18 @@
 
 	    *(*vb)++ = s;
 	    *(*vb)++ = t;
-        }
+	}
 	break;
     case CAIRO_GL_OPERAND_TEXTURE:
 	if (! operand->texture.texgen) {
-            cairo_surface_attributes_t *src_attributes = &operand->texture.attributes;
-            double s = x;
-            double t = y;
+	    cairo_surface_attributes_t *src_attributes = &operand->texture.attributes;
+	    double s = x;
+	    double t = y;
 
-            cairo_matrix_transform_point (&src_attributes->matrix, &s, &t);
-            *(*vb)++ = s;
-            *(*vb)++ = t;
-        }
-        break;
+	    cairo_matrix_transform_point (&src_attributes->matrix, &s, &t);
+	    *(*vb)++ = s;
+	    *(*vb)++ = t;
+	}
+	break;
     }
 }

Modified: trunk/Build/source/libs/cairo/cairo-src/src/cairo-gl-private.h
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/src/cairo-gl-private.h	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/src/cairo-gl-private.h	2018-10-20 03:19:36 UTC (rev 48952)
@@ -60,12 +60,15 @@
 
 #include <assert.h>
 
-#if CAIRO_HAS_GL_SURFACE
-#include <GL/gl.h>
-#include <GL/glext.h>
+#if CAIRO_HAS_GLESV3_SURFACE
+#include <GLES3/gl3.h>
+#include <GLES3/gl3ext.h>
 #elif CAIRO_HAS_GLESV2_SURFACE
 #include <GLES2/gl2.h>
 #include <GLES2/gl2ext.h>
+#elif CAIRO_HAS_GL_SURFACE
+#include <GL/gl.h>
+#include <GL/glext.h>
 #endif
 
 #include "cairo-gl-ext-def-private.h"
@@ -99,14 +102,15 @@
 
 typedef struct _cairo_gl_surface cairo_gl_surface_t;
 
-/* GL flavor */
+/* GL flavor is the type of GL supported by the underlying platform. */
 typedef enum cairo_gl_flavor {
     CAIRO_GL_FLAVOR_NONE = 0,
     CAIRO_GL_FLAVOR_DESKTOP = 1,
-    CAIRO_GL_FLAVOR_ES = 2
+    CAIRO_GL_FLAVOR_ES2 = 2,
+    CAIRO_GL_FLAVOR_ES3 = 3
 } cairo_gl_flavor_t;
 
-/* Indices for vertex attributes used by BindAttribLocation etc */
+/* Indices for vertex attributes used by BindAttribLocation, etc. */
 enum {
     CAIRO_GL_VERTEX_ATTRIB_INDEX = 0,
     CAIRO_GL_COLOR_ATTRIB_INDEX  = 1,
@@ -169,7 +173,7 @@
     GLuint fb; /* GL framebuffer object wrapping our data. */
     GLuint depth_stencil; /* GL renderbuffer object for holding stencil buffer clip. */
 
-#if CAIRO_HAS_GL_SURFACE
+#if CAIRO_HAS_GL_SURFACE || CAIRO_HAS_GLESV3_SURFACE
     GLuint msaa_rb; /* The ARB MSAA path uses a renderbuffer. */
     GLuint msaa_fb;
 #endif
@@ -178,8 +182,12 @@
     cairo_bool_t stencil_and_msaa_caps_initialized;
     cairo_bool_t supports_stencil; /* Stencil support for for non-texture surfaces. */
     cairo_bool_t supports_msaa;
+    GLint        num_samples;
     cairo_bool_t msaa_active; /* Whether the multisampling
 			         framebuffer is active or not. */
+    cairo_bool_t content_in_texture; /* whether we just uploaded image
+					to texture, used for certain
+					gles2 extensions and glesv3 */
     cairo_clip_t *clip_on_stencil_buffer;
 
     int owns_tex;
@@ -801,6 +809,10 @@
 				      cairo_composite_glyphs_info_t *info,
 				      cairo_clip_t		    *clip);
 
+cairo_private void
+_cairo_gl_ensure_framebuffer (cairo_gl_context_t *ctx,
+                              cairo_gl_surface_t *surface);
+
 cairo_private cairo_surface_t *
 _cairo_gl_surface_create_scratch (cairo_gl_context_t   *ctx,
 				  cairo_content_t	content,

Modified: trunk/Build/source/libs/cairo/cairo-src/src/cairo-gl-shaders.c
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/src/cairo-gl-shaders.c	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/src/cairo-gl-shaders.c	2018-10-20 03:19:36 UTC (rev 48952)
@@ -132,7 +132,7 @@
 
     _cairo_gl_shader_fini (entry->ctx, &entry->shader);
     if (entry->ctx->current_shader == &entry->shader)
-        entry->ctx->current_shader = NULL;
+	entry->ctx->current_shader = NULL;
     free (entry);
 }
 
@@ -171,12 +171,12 @@
     memset (ctx->vertex_shaders, 0, sizeof (ctx->vertex_shaders));
 
     status = _cairo_cache_init (&ctx->shaders,
-                                ctx->gl_flavor == CAIRO_GL_FLAVOR_DESKTOP ?
+				ctx->gl_flavor == CAIRO_GL_FLAVOR_DESKTOP ?
 				    _cairo_gl_shader_cache_equal_desktop :
 				    _cairo_gl_shader_cache_equal_gles2,
-                                NULL,
-                                _cairo_gl_shader_cache_destroy,
-                                CAIRO_GL_MAX_SHADERS_PER_CONTEXT);
+				NULL,
+				_cairo_gl_shader_cache_destroy,
+				CAIRO_GL_MAX_SHADERS_PER_CONTEXT);
     if (unlikely (status))
 	return status;
 
@@ -225,68 +225,68 @@
     switch (operand->type) {
     default:
     case CAIRO_GL_OPERAND_COUNT:
-        ASSERT_NOT_REACHED;
+	ASSERT_NOT_REACHED;
     case CAIRO_GL_OPERAND_NONE:
     case CAIRO_GL_OPERAND_CONSTANT:
-        return CAIRO_GL_VAR_NONE;
+	return CAIRO_GL_VAR_NONE;
     case CAIRO_GL_OPERAND_LINEAR_GRADIENT:
     case CAIRO_GL_OPERAND_RADIAL_GRADIENT_A0:
     case CAIRO_GL_OPERAND_RADIAL_GRADIENT_NONE:
     case CAIRO_GL_OPERAND_RADIAL_GRADIENT_EXT:
-        return operand->gradient.texgen ? CAIRO_GL_VAR_TEXGEN : CAIRO_GL_VAR_TEXCOORDS;
+	return operand->gradient.texgen ? CAIRO_GL_VAR_TEXGEN : CAIRO_GL_VAR_TEXCOORDS;
     case CAIRO_GL_OPERAND_TEXTURE:
-        return operand->texture.texgen ? CAIRO_GL_VAR_TEXGEN : CAIRO_GL_VAR_TEXCOORDS;
+	return operand->texture.texgen ? CAIRO_GL_VAR_TEXGEN : CAIRO_GL_VAR_TEXCOORDS;
     }
 }
 
 static void
 cairo_gl_shader_emit_variable (cairo_output_stream_t *stream,
-                               cairo_gl_var_type_t type,
-                               cairo_gl_tex_t name)
+			       cairo_gl_var_type_t type,
+			       cairo_gl_tex_t name)
 {
     switch (type) {
     default:
-        ASSERT_NOT_REACHED;
+	ASSERT_NOT_REACHED;
     case CAIRO_GL_VAR_NONE:
-        break;
+	break;
     case CAIRO_GL_VAR_TEXCOORDS:
-        _cairo_output_stream_printf (stream,
+	_cairo_output_stream_printf (stream,
 				     "attribute vec4 MultiTexCoord%d;\n"
-                                     "varying vec2 %s_texcoords;\n",
-                                     name,
-                                     operand_names[name]);
-        break;
+				     "varying vec2 %s_texcoords;\n",
+				     name,
+				     operand_names[name]);
+	break;
     case CAIRO_GL_VAR_TEXGEN:
-        _cairo_output_stream_printf (stream,
+	_cairo_output_stream_printf (stream,
 				     "uniform mat3 %s_texgen;\n"
-                                     "varying vec2 %s_texcoords;\n",
-                                     operand_names[name],
-                                     operand_names[name]);
-        break;
+				     "varying vec2 %s_texcoords;\n",
+				     operand_names[name],
+				     operand_names[name]);
+	break;
     }
 }
 
 static void
 cairo_gl_shader_emit_vertex (cairo_output_stream_t *stream,
-                             cairo_gl_var_type_t type,
-                             cairo_gl_tex_t name)
+			     cairo_gl_var_type_t type,
+			     cairo_gl_tex_t name)
 {
     switch (type) {
     default:
-        ASSERT_NOT_REACHED;
+	ASSERT_NOT_REACHED;
     case CAIRO_GL_VAR_NONE:
-        break;
+	break;
     case CAIRO_GL_VAR_TEXCOORDS:
-        _cairo_output_stream_printf (stream,
-                                     "    %s_texcoords = MultiTexCoord%d.xy;\n",
-                                     operand_names[name], name);
-        break;
+	_cairo_output_stream_printf (stream,
+				     "    %s_texcoords = MultiTexCoord%d.xy;\n",
+				     operand_names[name], name);
+	break;
 
     case CAIRO_GL_VAR_TEXGEN:
-        _cairo_output_stream_printf (stream,
+	_cairo_output_stream_printf (stream,
 				     "    %s_texcoords = (%s_texgen * Vertex.xyw).xy;\n",
-                                     operand_names[name], operand_names[name]);
-        break;
+				     operand_names[name], operand_names[name]);
+	break;
     }
 }
 
@@ -304,9 +304,9 @@
 
 static cairo_status_t
 cairo_gl_shader_get_vertex_source (cairo_gl_var_type_t src,
-                                   cairo_gl_var_type_t mask,
+				   cairo_gl_var_type_t mask,
 				   cairo_bool_t use_coverage,
-                                   cairo_gl_var_type_t dest,
+				   cairo_gl_var_type_t dest,
 				   char **out)
 {
     cairo_output_stream_t *stream = _cairo_memory_stream_create ();
@@ -361,9 +361,9 @@
 
 static void
 cairo_gl_shader_emit_color (cairo_output_stream_t *stream,
-                            cairo_gl_context_t *ctx,
-                            cairo_gl_operand_t *op,
-                            cairo_gl_tex_t name)
+			    cairo_gl_context_t *ctx,
+			    cairo_gl_operand_t *op,
+			    cairo_gl_tex_t name)
 {
     const char *namestr = operand_names[name];
     const char *rectstr = (ctx->tex_target == GL_TEXTURE_RECTANGLE ? "Rect" : "");
@@ -371,25 +371,25 @@
     switch (op->type) {
     case CAIRO_GL_OPERAND_COUNT:
     default:
-        ASSERT_NOT_REACHED;
-        break;
+	ASSERT_NOT_REACHED;
+	break;
     case CAIRO_GL_OPERAND_NONE:
-        _cairo_output_stream_printf (stream, 
-            "vec4 get_%s()\n"
-            "{\n"
-            "    return vec4 (0, 0, 0, 1);\n"
-            "}\n",
-            namestr);
-        break;
+	_cairo_output_stream_printf (stream,
+	    "vec4 get_%s()\n"
+	    "{\n"
+	    "    return vec4 (0, 0, 0, 1);\n"
+	    "}\n",
+	    namestr);
+	break;
     case CAIRO_GL_OPERAND_CONSTANT:
-        _cairo_output_stream_printf (stream, 
-            "uniform vec4 %s_constant;\n"
-            "vec4 get_%s()\n"
-            "{\n"
-            "    return %s_constant;\n"
-            "}\n",
-            namestr, namestr, namestr);
-        break;
+	_cairo_output_stream_printf (stream,
+	    "uniform vec4 %s_constant;\n"
+	    "vec4 get_%s()\n"
+	    "{\n"
+	    "    return %s_constant;\n"
+	    "}\n",
+	    namestr, namestr, namestr);
+	break;
     case CAIRO_GL_OPERAND_TEXTURE:
 	_cairo_output_stream_printf (stream,
 	     "uniform sampler2D%s %s_sampler;\n"
@@ -398,7 +398,8 @@
 	     "vec4 get_%s()\n"
 	     "{\n",
 	     rectstr, namestr, namestr, namestr, namestr);
-	if (ctx->gl_flavor == CAIRO_GL_FLAVOR_ES &&
+	if ((ctx->gl_flavor == CAIRO_GL_FLAVOR_ES3 ||
+	     ctx->gl_flavor == CAIRO_GL_FLAVOR_ES2) &&
 	    _cairo_gl_shader_needs_border_fade (op))
 	{
 	    _cairo_output_stream_printf (stream,
@@ -415,7 +416,7 @@
 		"}\n",
 		rectstr, namestr, namestr, namestr);
 	}
-        break;
+	break;
     case CAIRO_GL_OPERAND_LINEAR_GRADIENT:
 	_cairo_output_stream_printf (stream,
 	    "varying vec2 %s_texcoords;\n"
@@ -425,7 +426,8 @@
 	    "vec4 get_%s()\n"
 	    "{\n",
 	    namestr, namestr, rectstr, namestr, namestr);
-	if (ctx->gl_flavor == CAIRO_GL_FLAVOR_ES &&
+	if ((ctx->gl_flavor == CAIRO_GL_FLAVOR_ES3 ||
+	     ctx->gl_flavor == CAIRO_GL_FLAVOR_ES2) &&
 	    _cairo_gl_shader_needs_border_fade (op))
 	{
 	    _cairo_output_stream_printf (stream,
@@ -462,7 +464,8 @@
 	    "    float is_valid = step (-%s_radius_0, t * %s_circle_d.z);\n",
 	    namestr, namestr, rectstr, namestr, namestr, namestr, namestr,
 	    namestr, namestr, namestr, namestr, namestr);
-	if (ctx->gl_flavor == CAIRO_GL_FLAVOR_ES &&
+	if ((ctx->gl_flavor == CAIRO_GL_FLAVOR_ES3 ||
+	     ctx->gl_flavor == CAIRO_GL_FLAVOR_ES2) &&
 	    _cairo_gl_shader_needs_border_fade (op))
 	{
 	    _cairo_output_stream_printf (stream,
@@ -507,7 +510,8 @@
 	    "    float upper_t = mix (t.y, t.x, is_valid.x);\n",
 	    namestr, namestr, rectstr, namestr, namestr, namestr, namestr,
 	    namestr, namestr, namestr, namestr, namestr, namestr);
-	if (ctx->gl_flavor == CAIRO_GL_FLAVOR_ES &&
+	if ((ctx->gl_flavor == CAIRO_GL_FLAVOR_ES3 ||
+	     ctx->gl_flavor == CAIRO_GL_FLAVOR_ES2) &&
 	    _cairo_gl_shader_needs_border_fade (op))
 	{
 	    _cairo_output_stream_printf (stream,
@@ -653,11 +657,11 @@
 
 static cairo_status_t
 cairo_gl_shader_get_fragment_source (cairo_gl_context_t *ctx,
-                                     cairo_gl_shader_in_t in,
-                                     cairo_gl_operand_t *src,
-                                     cairo_gl_operand_t *mask,
+				     cairo_gl_shader_in_t in,
+				     cairo_gl_operand_t *src,
+				     cairo_gl_operand_t *mask,
 				     cairo_bool_t use_coverage,
-                                     cairo_gl_operand_type_t dest_type,
+				     cairo_gl_operand_type_t dest_type,
 				     char **out)
 {
     cairo_output_stream_t *stream = _cairo_memory_stream_create ();
@@ -674,7 +678,8 @@
     _cairo_gl_shader_emit_wrap (ctx, stream, src, CAIRO_GL_TEX_SOURCE);
     _cairo_gl_shader_emit_wrap (ctx, stream, mask, CAIRO_GL_TEX_MASK);
 
-    if (ctx->gl_flavor == CAIRO_GL_FLAVOR_ES) {
+    if (ctx->gl_flavor == CAIRO_GL_FLAVOR_ES3 ||
+	ctx->gl_flavor == CAIRO_GL_FLAVOR_ES2) {
 	if (_cairo_gl_shader_needs_border_fade (src))
 	    _cairo_gl_shader_emit_border_fade (stream, src, CAIRO_GL_TEX_SOURCE);
 	if (_cairo_gl_shader_needs_border_fade (mask))
@@ -691,35 +696,35 @@
     }
 
     _cairo_output_stream_printf (stream,
-        "void main()\n"
-        "{\n");
+	"void main()\n"
+	"{\n");
     switch (in) {
     case CAIRO_GL_SHADER_IN_COUNT:
     default:
-        ASSERT_NOT_REACHED;
+	ASSERT_NOT_REACHED;
     case CAIRO_GL_SHADER_IN_NORMAL:
-        _cairo_output_stream_printf (stream,
-            "    gl_FragColor = get_source() * get_mask().a%s;\n",
+	_cairo_output_stream_printf (stream,
+	    "    gl_FragColor = get_source() * get_mask().a%s;\n",
 	    coverage_str);
-        break;
+	break;
     case CAIRO_GL_SHADER_IN_CA_SOURCE:
-        _cairo_output_stream_printf (stream,
-            "    gl_FragColor = get_source() * get_mask()%s;\n",
+	_cairo_output_stream_printf (stream,
+	    "    gl_FragColor = get_source() * get_mask()%s;\n",
 	    coverage_str);
-        break;
+	break;
     case CAIRO_GL_SHADER_IN_CA_SOURCE_ALPHA:
-        _cairo_output_stream_printf (stream,
-            "    gl_FragColor = get_source().a * get_mask()%s;\n",
+	_cairo_output_stream_printf (stream,
+	    "    gl_FragColor = get_source().a * get_mask()%s;\n",
 	    coverage_str);
-        break;
+	break;
     }
 
     _cairo_output_stream_write (stream,
-                                "}\n\0", 3);
+				"}\n\0", 3);
 
     status = _cairo_memory_stream_destroy (stream, &source, &length);
     if (unlikely (status))
-        return status;
+	return status;
 
     *out = (char *) source;
     return CAIRO_STATUS_SUCCESS;
@@ -995,7 +1000,7 @@
 		      cairo_gl_shader_t *shader)
 {
     if (ctx->current_shader == shader)
-        return;
+	return;
 
     if (shader)
 	ctx->dispatch.UseProgram (shader->program);
@@ -1007,11 +1012,11 @@
 
 cairo_status_t
 _cairo_gl_get_shader_by_type (cairo_gl_context_t *ctx,
-                              cairo_gl_operand_t *source,
-                              cairo_gl_operand_t *mask,
+			      cairo_gl_operand_t *source,
+			      cairo_gl_operand_t *mask,
 			      cairo_bool_t use_coverage,
-                              cairo_gl_shader_in_t in,
-                              cairo_gl_shader_t **shader)
+			      cairo_gl_shader_in_t in,
+			      cairo_gl_shader_t **shader)
 {
     cairo_shader_cache_entry_t lookup, *entry;
     char *fs_source;
@@ -1040,8 +1045,8 @@
 
     entry = _cairo_cache_lookup (&ctx->shaders, &lookup.base);
     if (entry) {
-        assert (entry->shader.program);
-        *shader = &entry->shader;
+	assert (entry->shader.program);
+	*shader = &entry->shader;
 	return CAIRO_STATUS_SUCCESS;
     }
 
@@ -1055,10 +1060,10 @@
     if (unlikely (status))
 	return status;
 
-    entry = malloc (sizeof (cairo_shader_cache_entry_t));
+    entry = _cairo_malloc (sizeof (cairo_shader_cache_entry_t));
     if (unlikely (entry == NULL)) {
-        free (fs_source);
-        return _cairo_error (CAIRO_STATUS_NO_MEMORY);
+	free (fs_source);
+	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
     }
 
     memcpy (entry, &lookup, sizeof (cairo_shader_cache_entry_t));

Modified: trunk/Build/source/libs/cairo/cairo-src/src/cairo-gl-source.c
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/src/cairo-gl-source.c	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/src/cairo-gl-source.c	2018-10-20 03:19:36 UTC (rev 48952)
@@ -69,7 +69,7 @@
     if (pattern == NULL)
 	return _cairo_gl_white_source ();
 
-    source = malloc (sizeof (*source));
+    source = _cairo_malloc (sizeof (*source));
     if (unlikely (source == NULL))
 	return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
 
@@ -76,7 +76,8 @@
     _cairo_surface_init (&source->base,
 			 &cairo_gl_source_backend,
 			 NULL, /* device */
-			 CAIRO_CONTENT_COLOR_ALPHA);
+			 CAIRO_CONTENT_COLOR_ALPHA,
+			 FALSE); /* is_vector */
 
     *src_x = *src_y = 0;
     status = _cairo_gl_operand_init (&source->operand, pattern,
@@ -96,7 +97,7 @@
 {
     cairo_gl_source_t *source;
 
-    source = malloc (sizeof (*source));
+    source = _cairo_malloc (sizeof (*source));
     if (unlikely (source == NULL))
 	return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
 
@@ -103,7 +104,8 @@
     _cairo_surface_init (&source->base,
 			 &cairo_gl_source_backend,
 			 NULL, /* device */
-			 CAIRO_CONTENT_COLOR_ALPHA);
+			 CAIRO_CONTENT_COLOR_ALPHA,
+			 FALSE); /* is_vector */
 
     _cairo_gl_solid_operand_init (&source->operand, CAIRO_COLOR_WHITE);
 

Modified: trunk/Build/source/libs/cairo/cairo-src/src/cairo-gl-spans-compositor.c
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/src/cairo-gl-spans-compositor.c	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/src/cairo-gl-spans-compositor.c	2018-10-20 03:19:36 UTC (rev 48952)
@@ -139,27 +139,27 @@
 	      r->xmax, y + height,
 	      0);
     } else {
-        if (spans[0].x != r->xmin) {
+	if (spans[0].x != r->xmin) {
 	    emit (r->ctx,
 		  r->xmin, y,
 		  spans[0].x,     y + height,
 		  0);
-        }
+	}
 
-        do {
+	do {
 	    emit (r->ctx,
 		  spans[0].x, y,
 		  spans[1].x, y + height,
 		  r->opacity * spans[0].coverage);
-            spans++;
-        } while (--num_spans > 1);
+	    spans++;
+	} while (--num_spans > 1);
 
-        if (spans[0].x != r->xmax) {
+	if (spans[0].x != r->xmax) {
 	    emit (r->ctx,
 		  spans[0].x,     y,
 		  r->xmax, y + height,
 		  0);
-        }
+	}
     }
 
     r->ymin = y + height;
@@ -189,27 +189,27 @@
 	      r->xmax, y + height,
 	      0);
     } else {
-        if (spans[0].x != r->xmin) {
+	if (spans[0].x != r->xmin) {
 	    emit (r->ctx,
 		  r->xmin, y,
 		  spans[0].x,     y + height,
 		  0);
-        }
+	}
 
-        do {
+	do {
 	    emit (r->ctx,
 		  spans[0].x, y,
 		  spans[1].x, y + height,
 		  r->opacity * spans[0].coverage);
-            spans++;
-        } while (--num_spans > 1);
+	    spans++;
+	} while (--num_spans > 1);
 
-        if (spans[0].x != r->xmax) {
+	if (spans[0].x != r->xmax) {
 	    emit (r->ctx,
 		  spans[0].x,     y,
 		  r->xmax, y + height,
 		  0);
-        }
+	}
     }
 
     r->ymin = y + height;
@@ -273,13 +273,13 @@
     TRACE ((stderr, "%s\n", __FUNCTION__));
     status = _cairo_gl_composite_init (&setup, op, _dst, FALSE);
     if (unlikely (status))
-        goto FAIL;
+	goto FAIL;
 
    _cairo_gl_composite_set_solid_source (&setup, color);
 
     status = _cairo_gl_composite_begin (&setup, &ctx);
     if (unlikely (status))
-        goto FAIL;
+	goto FAIL;
 
     emit_aligned_boxes (ctx, boxes);
     status = _cairo_gl_context_release (ctx, CAIRO_STATUS_SUCCESS);
@@ -341,7 +341,7 @@
 
     status = _cairo_gl_composite_init (&setup, CAIRO_OPERATOR_SOURCE, _dst, FALSE);
     if (unlikely (status))
-        goto FAIL;
+	goto FAIL;
 
     _cairo_gl_composite_set_source_operand (&setup, &src->operand);
     _cairo_gl_operand_translate (&setup.src, -dx, -dy);
@@ -348,7 +348,7 @@
 
     status = _cairo_gl_composite_begin (&setup, &ctx);
     if (unlikely (status))
-        goto FAIL;
+	goto FAIL;
 
     emit_aligned_boxes (ctx, boxes);
     status = _cairo_gl_context_release (ctx, CAIRO_STATUS_SUCCESS);
@@ -396,7 +396,7 @@
 
     status = _cairo_gl_composite_init (&setup, op, _dst, FALSE);
     if (unlikely (status))
-        goto FAIL;
+	goto FAIL;
 
     _cairo_gl_composite_set_source_operand (&setup,
 					    src_operand);
@@ -408,7 +408,7 @@
 
     status = _cairo_gl_composite_begin (&setup, &ctx);
     if (unlikely (status))
-        goto FAIL;
+	goto FAIL;
 
     emit_aligned_boxes (ctx, boxes);
     status = _cairo_gl_context_release (ctx, CAIRO_STATUS_SUCCESS);
@@ -454,10 +454,10 @@
 	return CAIRO_INT_STATUS_UNSUPPORTED;
 
     status = _cairo_gl_composite_init (&r->setup,
-                                       op, (cairo_gl_surface_t *)composite->surface,
-                                       FALSE);
+				       op, (cairo_gl_surface_t *)composite->surface,
+				       FALSE);
     if (unlikely (status))
-        goto FAIL;
+	goto FAIL;
 
     status = _cairo_gl_composite_set_source (&r->setup, source,
 					     &composite->source_sample_area,
@@ -464,7 +464,7 @@
 					     &composite->unbounded,
 					     TRUE);
     if (unlikely (status))
-        goto FAIL;
+	goto FAIL;
 
     r->opacity = 1.0;
     if (composite->mask_pattern.base.type == CAIRO_PATTERN_TYPE_SOLID) {
@@ -483,7 +483,7 @@
 
     status = _cairo_gl_composite_begin (&r->setup, &r->ctx);
     if (unlikely (status))
-        goto FAIL;
+	goto FAIL;
 
     r->emit = _cairo_gl_context_choose_emit_span (r->ctx);
     if (composite->is_bounded) {
@@ -491,13 +491,13 @@
 	    r->base.render_rows = _cairo_gl_bounded_opaque_spans;
 	else
 	    r->base.render_rows = _cairo_gl_bounded_spans;
-        r->base.finish = _cairo_gl_finish_bounded_spans;
+	r->base.finish = _cairo_gl_finish_bounded_spans;
     } else {
 	if (needs_clip)
 	    r->base.render_rows = _cairo_gl_clipped_spans;
 	else
 	    r->base.render_rows = _cairo_gl_unbounded_spans;
-        r->base.finish = _cairo_gl_finish_unbounded_spans;
+	r->base.finish = _cairo_gl_finish_unbounded_spans;
 	r->xmin = composite->unbounded.x;
 	r->xmax = composite->unbounded.x + composite->unbounded.width;
 	r->ymin = composite->unbounded.y;
@@ -528,10 +528,11 @@
 const cairo_compositor_t *
 _cairo_gl_span_compositor_get (void)
 {
+    static cairo_atomic_once_t once = CAIRO_ATOMIC_ONCE_INIT;
     static cairo_spans_compositor_t spans;
     static cairo_compositor_t shape;
 
-    if (spans.base.delegate == NULL) {
+    if (_cairo_atomic_init_once_enter(&once)) {
 	/* The fallback to traps here is essentially just for glyphs... */
 	_cairo_shape_mask_compositor_init (&shape,
 					   _cairo_gl_traps_compositor_get());
@@ -547,6 +548,8 @@
 	//spans.check_span_renderer = check_span_renderer;
 	spans.renderer_init = _cairo_gl_span_renderer_init;
 	spans.renderer_fini = _cairo_gl_span_renderer_fini;
+
+	_cairo_atomic_init_once_leave(&once);
     }
 
     return &spans.base;

Modified: trunk/Build/source/libs/cairo/cairo-src/src/cairo-gl-surface.c
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/src/cairo-gl-surface.c	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/src/cairo-gl-surface.c	2018-10-20 03:19:36 UTC (rev 48952)
@@ -389,11 +389,13 @@
     _cairo_surface_init (&surface->base,
 			 &_cairo_gl_surface_backend,
 			 device,
-			 content);
+			 content,
+			 FALSE); /* is_vector */
 
     surface->width = width;
     surface->height = height;
     surface->needs_update = FALSE;
+    surface->content_in_texture = FALSE;
 
     _cairo_gl_surface_embedded_operand_init (surface);
 }
@@ -432,6 +434,7 @@
     _cairo_gl_surface_init (&ctx->base, surface, content, width, height);
 
     surface->supports_msaa = ctx->supports_msaa;
+    surface->num_samples = ctx->num_samples;
     surface->supports_stencil = TRUE;
 
     /* Create the texture used to store the surface's data. */
@@ -523,7 +526,7 @@
 
 static cairo_status_t
 _cairo_gl_surface_clear (cairo_gl_surface_t  *surface,
-                         const cairo_color_t *color)
+			 const cairo_color_t *color)
 {
     cairo_gl_context_t *ctx;
     cairo_status_t status;
@@ -535,16 +538,16 @@
 
     _cairo_gl_context_set_destination (ctx, surface, surface->msaa_active);
     if (surface->base.content & CAIRO_CONTENT_COLOR) {
-        r = color->red   * color->alpha;
-        g = color->green * color->alpha;
-        b = color->blue  * color->alpha;
+	r = color->red   * color->alpha;
+	g = color->green * color->alpha;
+	b = color->blue  * color->alpha;
     } else {
-        r = g = b = 0;
+	r = g = b = 0;
     }
     if (surface->base.content & CAIRO_CONTENT_ALPHA) {
-        a = color->alpha;
+	a = color->alpha;
     } else {
-        a = 1.0;
+	a = 1.0;
     }
 
     glDisable (GL_SCISSOR_TEST);
@@ -711,11 +714,11 @@
     if (unlikely (abstract_surface->finished)) {
 	_cairo_surface_set_error (abstract_surface,
 				  _cairo_error (CAIRO_STATUS_SURFACE_FINISHED));
-        return;
+	return;
     }
 
     if (! _cairo_surface_is_gl (abstract_surface) ||
-        _cairo_gl_surface_is_texture (surface)) {
+	_cairo_gl_surface_is_texture (surface)) {
 	_cairo_surface_set_error (abstract_surface,
 				  _cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH));
 	return;
@@ -760,7 +763,7 @@
     if (unlikely (abstract_surface->finished)) {
 	_cairo_surface_set_error (abstract_surface,
 				  _cairo_error (CAIRO_STATUS_SURFACE_FINISHED));
-        return;
+	return;
     }
 
     if (! _cairo_surface_is_gl (abstract_surface)) {
@@ -771,11 +774,11 @@
 
     if (! _cairo_gl_surface_is_texture (surface)) {
 	cairo_gl_context_t *ctx;
-        cairo_status_t status;
+	cairo_status_t status;
 
-        status = _cairo_gl_context_acquire (surface->base.device, &ctx);
-        if (unlikely (status))
-            return;
+	status = _cairo_gl_context_acquire (surface->base.device, &ctx);
+	if (unlikely (status))
+	    return;
 
 	/* For swapping on EGL, at least, we need a valid context/target. */
 	_cairo_gl_context_set_destination (ctx, surface, FALSE);
@@ -784,9 +787,9 @@
 
 	ctx->swap_buffers (ctx, surface);
 
-        status = _cairo_gl_context_release (ctx, status);
-        if (status)
-            status = _cairo_surface_set_error (abstract_surface, status);
+	status = _cairo_gl_context_release (ctx, status);
+	if (status)
+	    status = _cairo_surface_set_error (abstract_surface, status);
     }
 }
 
@@ -801,7 +804,7 @@
     cairo_status_t status;
 
     if (! _cairo_gl_surface_size_valid (abstract_surface, width, height))
-        return _cairo_image_surface_create_with_content (content, width, height);
+	return _cairo_image_surface_create_with_content (content, width, height);
 
     status = _cairo_gl_context_acquire (surface->device, &ctx);
     if (unlikely (status))
@@ -811,8 +814,8 @@
 
     status = _cairo_gl_context_release (ctx, status);
     if (unlikely (status)) {
-        cairo_surface_destroy (surface);
-        return _cairo_surface_create_in_error (status);
+	cairo_surface_destroy (surface);
+	return _cairo_surface_create_in_error (status);
     }
 
     return surface;
@@ -833,13 +836,13 @@
     status = _cairo_gl_composite_init (&setup, CAIRO_OPERATOR_SOURCE,
 				       dst, FALSE);
     if (unlikely (status))
-        goto CLEANUP;
+	goto CLEANUP;
 
     _cairo_gl_composite_set_solid_source (&setup, CAIRO_COLOR_BLACK);
 
     status = _cairo_gl_composite_begin (&setup, &ctx);
     if (unlikely (status))
-        goto CLEANUP;
+	goto CLEANUP;
 
     _cairo_gl_context_emit_rect (ctx, x, y, x + width, y + height);
 
@@ -867,6 +870,7 @@
     cairo_image_surface_t *clone = NULL;
     cairo_gl_context_t *ctx;
     int cpp;
+    cairo_image_surface_t *rgba_clone = NULL;
     cairo_int_status_t status = CAIRO_INT_STATUS_SUCCESS;
 
     status = _cairo_gl_context_acquire (dst->base.device, &ctx);
@@ -873,6 +877,47 @@
     if (unlikely (status))
 	return status;
 
+    if (_cairo_gl_get_flavor () == CAIRO_GL_FLAVOR_ES3 ||
+	_cairo_gl_get_flavor () == CAIRO_GL_FLAVOR_ES2) {
+	pixman_format_code_t pixman_format;
+	cairo_surface_pattern_t pattern;
+	cairo_bool_t require_conversion = FALSE;
+	pixman_format = _cairo_is_little_endian () ? PIXMAN_a8b8g8r8 : PIXMAN_r8g8b8a8;
+
+	if (src->base.content != CAIRO_CONTENT_ALPHA) {
+	    if (src->pixman_format != pixman_format)
+		require_conversion = TRUE;
+	}
+	else if (dst->base.content != CAIRO_CONTENT_ALPHA) {
+	    require_conversion = TRUE;
+	}
+	else if (src->pixman_format != PIXMAN_a8) {
+	    pixman_format = PIXMAN_a8;
+	    require_conversion = TRUE;
+	}
+
+	if (require_conversion) {
+	    rgba_clone = (cairo_image_surface_t *)
+		_cairo_image_surface_create_with_pixman_format (NULL,
+								pixman_format,
+								src->width,
+								src->height,
+								0);
+	    if (unlikely (rgba_clone->base.status))
+		goto FAIL;
+
+	    _cairo_pattern_init_for_surface (&pattern, &src->base);
+	    status = _cairo_surface_paint (&rgba_clone->base,
+					   CAIRO_OPERATOR_SOURCE,
+					   &pattern.base, NULL);
+	    _cairo_pattern_fini (&pattern.base);
+	    if (unlikely (status))
+		goto FAIL;
+
+	    src = rgba_clone;
+	}
+    }
+
     if (! _cairo_gl_get_image_format_and_type (ctx->gl_flavor,
 					       src->pixman_format,
 					       &internal_format,
@@ -890,7 +935,7 @@
 	is_supported =
 	    _cairo_gl_get_image_format_and_type (ctx->gl_flavor,
 						 clone->pixman_format,
-		                                 &internal_format,
+						 &internal_format,
 						 &format,
 						 &type,
 						 &has_alpha,
@@ -921,7 +966,7 @@
 	 *     alignment constraint
 	 */
 	if (src->stride < 0 ||
-	    (ctx->gl_flavor == CAIRO_GL_FLAVOR_ES &&
+	    (ctx->gl_flavor == CAIRO_GL_FLAVOR_ES2 &&
 	     (src->width * cpp < src->stride - 3 ||
 	      width != src->width)))
 	{
@@ -937,11 +982,20 @@
 	else
 	{
 	    glPixelStorei (GL_UNPACK_ALIGNMENT, 4);
-	    if (ctx->gl_flavor == CAIRO_GL_FLAVOR_DESKTOP)
+	    if (ctx->gl_flavor == CAIRO_GL_FLAVOR_DESKTOP ||
+		ctx->gl_flavor == CAIRO_GL_FLAVOR_ES3)
 		glPixelStorei (GL_UNPACK_ROW_LENGTH, src->stride / cpp);
 	}
 
-        _cairo_gl_context_activate (ctx, CAIRO_GL_TEX_TEMP);
+	/* we must resolve the renderbuffer to texture before we
+	   upload image */
+	status = _cairo_gl_surface_resolve_multisampling (dst);
+	if (unlikely (status)) {
+	    free (data_start_gles2);
+	    goto FAIL;
+	}
+
+	_cairo_gl_context_activate (ctx, CAIRO_GL_TEX_TEMP);
 	glBindTexture (ctx->tex_target, dst->tex);
 	glTexParameteri (ctx->tex_target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
 	glTexParameteri (ctx->tex_target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
@@ -960,26 +1014,28 @@
 						  dst_x, dst_y,
 						  width, height);
 	}
+	if (ctx->gl_flavor == CAIRO_GL_FLAVOR_ES3)
+	    dst->content_in_texture = TRUE;
     } else {
-        cairo_surface_t *tmp;
+	cairo_surface_t *tmp;
 
-        tmp = _cairo_gl_surface_create_scratch (ctx,
-                                                dst->base.content,
-                                                width, height);
-        if (unlikely (tmp->status))
-            goto FAIL;
+	tmp = _cairo_gl_surface_create_scratch (ctx,
+						dst->base.content,
+						width, height);
+	if (unlikely (tmp->status))
+	    goto FAIL;
 
-        status = _cairo_gl_surface_draw_image ((cairo_gl_surface_t *) tmp,
-                                               src,
-                                               src_x, src_y,
-                                               width, height,
-                                               0, 0, force_flush);
-        if (status == CAIRO_INT_STATUS_SUCCESS) {
-            cairo_surface_pattern_t tmp_pattern;
+	status = _cairo_gl_surface_draw_image ((cairo_gl_surface_t *) tmp,
+					       src,
+					       src_x, src_y,
+					       width, height,
+					       0, 0, force_flush);
+	if (status == CAIRO_INT_STATUS_SUCCESS) {
+	    cairo_surface_pattern_t tmp_pattern;
 	    cairo_rectangle_int_t r;
 	    cairo_clip_t *clip;
 
-            _cairo_pattern_init_for_surface (&tmp_pattern, tmp);
+	    _cairo_pattern_init_for_surface (&tmp_pattern, tmp);
 	    cairo_matrix_init_translate (&tmp_pattern.base.matrix,
 					 -dst_x, -dst_y);
 	    tmp_pattern.base.filter = CAIRO_FILTER_NEAREST;
@@ -995,10 +1051,12 @@
 					   &tmp_pattern.base,
 					   clip);
 	    _cairo_clip_destroy (clip);
-            _cairo_pattern_fini (&tmp_pattern.base);
-        }
+	    _cairo_pattern_fini (&tmp_pattern.base);
+	}
 
-        cairo_surface_destroy (tmp);
+	cairo_surface_destroy (tmp);
+	if (ctx->gl_flavor == CAIRO_GL_FLAVOR_ES3)
+	    dst->content_in_texture = TRUE;
     }
 
 FAIL:
@@ -1005,8 +1063,11 @@
     status = _cairo_gl_context_release (ctx, status);
 
     if (clone)
-        cairo_surface_destroy (&clone->base);
+	cairo_surface_destroy (&clone->base);
 
+    if (rgba_clone)
+	cairo_surface_destroy (&rgba_clone->base);
+
     return status;
 }
 
@@ -1025,21 +1086,21 @@
 
     status = _cairo_gl_context_acquire (surface->base.device, &ctx);
     if (unlikely (status))
-        return status;
+	return status;
 
     if (ctx->operands[CAIRO_GL_TEX_SOURCE].type == CAIRO_GL_OPERAND_TEXTURE &&
-        ctx->operands[CAIRO_GL_TEX_SOURCE].texture.surface == surface)
-        _cairo_gl_context_destroy_operand (ctx, CAIRO_GL_TEX_SOURCE);
+	ctx->operands[CAIRO_GL_TEX_SOURCE].texture.surface == surface)
+	_cairo_gl_context_destroy_operand (ctx, CAIRO_GL_TEX_SOURCE);
     if (ctx->operands[CAIRO_GL_TEX_MASK].type == CAIRO_GL_OPERAND_TEXTURE &&
-        ctx->operands[CAIRO_GL_TEX_MASK].texture.surface == surface)
-        _cairo_gl_context_destroy_operand (ctx, CAIRO_GL_TEX_MASK);
+	ctx->operands[CAIRO_GL_TEX_MASK].texture.surface == surface)
+	_cairo_gl_context_destroy_operand (ctx, CAIRO_GL_TEX_MASK);
     if (ctx->current_target == surface)
 	ctx->current_target = NULL;
 
     if (surface->fb)
-        ctx->dispatch.DeleteFramebuffers (1, &surface->fb);
+	ctx->dispatch.DeleteFramebuffers (1, &surface->fb);
     if (surface->depth_stencil)
-        ctx->dispatch.DeleteRenderbuffers (1, &surface->depth_stencil);
+	ctx->dispatch.DeleteRenderbuffers (1, &surface->depth_stencil);
     if (surface->owns_tex)
 	glDeleteTextures (1, &surface->tex);
 
@@ -1046,7 +1107,7 @@
     if (surface->msaa_depth_stencil)
 	ctx->dispatch.DeleteRenderbuffers (1, &surface->msaa_depth_stencil);
 
-#if CAIRO_HAS_GL_SURFACE
+#if CAIRO_HAS_GL_SURFACE || CAIRO_HAS_GLESV3_SURFACE
     if (surface->msaa_fb)
 	ctx->dispatch.DeleteFramebuffers (1, &surface->msaa_fb);
     if (surface->msaa_rb)
@@ -1098,7 +1159,8 @@
 	return NULL;
     }
 
-    if (_cairo_gl_surface_flavor (surface) == CAIRO_GL_FLAVOR_ES) {
+    if (_cairo_gl_surface_flavor (surface) == CAIRO_GL_FLAVOR_ES3 ||
+	_cairo_gl_surface_flavor (surface) == CAIRO_GL_FLAVOR_ES2) {
 	/* If only RGBA is supported, we must download data in a compatible
 	 * format. This means that pixman will convert the data on the CPU when
 	 * interacting with other image surfaces. For ALPHA, GLES2 does not
@@ -1147,13 +1209,29 @@
      * fall back instead.
      */
     _cairo_gl_composite_flush (ctx);
-    _cairo_gl_context_set_destination (ctx, surface, FALSE);
 
+    if (ctx->gl_flavor != CAIRO_GL_FLAVOR_ES3) {
+	_cairo_gl_context_set_destination (ctx, surface, FALSE);
+    } else {
+	if (surface->content_in_texture) {
+	    _cairo_gl_ensure_framebuffer (ctx, surface);
+	    ctx->dispatch.BindFramebuffer (GL_FRAMEBUFFER, surface->fb);
+	} else {
+	    status = _cairo_gl_surface_resolve_multisampling (surface);
+	    if (unlikely (status)) {
+		status = _cairo_gl_context_release (ctx, status);
+		cairo_surface_destroy (&image->base);
+		return _cairo_image_surface_create_in_error (status);
+	    }
+	}
+    }
+
     flipped = ! _cairo_gl_surface_is_texture (surface);
     mesa_invert = flipped && ctx->has_mesa_pack_invert;
 
     glPixelStorei (GL_PACK_ALIGNMENT, 4);
-    if (ctx->gl_flavor == CAIRO_GL_FLAVOR_DESKTOP)
+    if (ctx->gl_flavor == CAIRO_GL_FLAVOR_DESKTOP ||
+	ctx->gl_flavor == CAIRO_GL_FLAVOR_ES3)
 	glPixelStorei (GL_PACK_ROW_LENGTH, image->stride / cpp);
     if (mesa_invert)
 	glPixelStorei (GL_PACK_INVERT_MESA, 1);
@@ -1181,7 +1259,7 @@
 	uint8_t *bot = image->data + (image->height-1)*image->stride;
 
 	if (image->stride > (int)sizeof(stack)) {
-	    row = malloc (image->stride);
+	    row = _cairo_malloc (image->stride);
 	    if (unlikely (row == NULL)) {
 		cairo_surface_destroy (&image->base);
 		return _cairo_image_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
@@ -1291,13 +1369,13 @@
 
     status = _cairo_gl_context_acquire (surface->base.device, &ctx);
     if (unlikely (status))
-        return status;
+	return status;
 
     if ((ctx->operands[CAIRO_GL_TEX_SOURCE].type == CAIRO_GL_OPERAND_TEXTURE &&
-         ctx->operands[CAIRO_GL_TEX_SOURCE].texture.surface == surface) ||
-        (ctx->operands[CAIRO_GL_TEX_MASK].type == CAIRO_GL_OPERAND_TEXTURE &&
-         ctx->operands[CAIRO_GL_TEX_MASK].texture.surface == surface) ||
-        (ctx->current_target == surface))
+	 ctx->operands[CAIRO_GL_TEX_SOURCE].texture.surface == surface) ||
+	(ctx->operands[CAIRO_GL_TEX_MASK].type == CAIRO_GL_OPERAND_TEXTURE &&
+	 ctx->operands[CAIRO_GL_TEX_MASK].texture.surface == surface) ||
+	(ctx->current_target == surface))
       _cairo_gl_composite_flush (ctx);
 
     status = _cairo_gl_surface_resolve_multisampling (surface);
@@ -1318,8 +1396,11 @@
 	return CAIRO_INT_STATUS_SUCCESS;
 
     /* GLES surfaces do not need explicit resolution. */
-    if (((cairo_gl_context_t *) surface->base.device)->gl_flavor == CAIRO_GL_FLAVOR_ES)
+    if (((cairo_gl_context_t *) surface->base.device)->gl_flavor == CAIRO_GL_FLAVOR_ES2)
 	return CAIRO_INT_STATUS_SUCCESS;
+    else if (((cairo_gl_context_t *) surface->base.device)->gl_flavor == CAIRO_GL_FLAVOR_ES3 &&
+	     surface->content_in_texture)
+	return CAIRO_INT_STATUS_SUCCESS;
 
     if (! _cairo_gl_surface_is_texture (surface))
 	return CAIRO_INT_STATUS_SUCCESS;
@@ -1328,10 +1409,20 @@
     if (unlikely (status))
 	return status;
 
+#if CAIRO_HAS_GLESV3_SURFACE
+    _cairo_gl_composite_flush (ctx);
+    ctx->current_target = NULL;
+    _cairo_gl_context_bind_framebuffer (ctx, surface, FALSE);
+    if (ctx->gl_flavor == CAIRO_GL_FLAVOR_ES3)
+	surface->content_in_texture = TRUE;
+
+#elif CAIRO_HAS_GL_SURFACE
     ctx->current_target = surface;
+    _cairo_gl_context_bind_framebuffer (ctx, surface, FALSE);
 
-#if CAIRO_HAS_GL_SURFACE
-    _cairo_gl_context_bind_framebuffer (ctx, surface, FALSE);
+#else
+    ctx->current_target = surface;
+
 #endif
 
     status = _cairo_gl_context_release (ctx, status);
@@ -1353,14 +1444,14 @@
 {
     /* simplify the common case of clearing the surface */
     if (clip == NULL) {
-        if (op == CAIRO_OPERATOR_CLEAR)
-            return _cairo_gl_surface_clear (surface, CAIRO_COLOR_TRANSPARENT);
+	if (op == CAIRO_OPERATOR_CLEAR)
+	    return _cairo_gl_surface_clear (surface, CAIRO_COLOR_TRANSPARENT);
        else if (source->type == CAIRO_PATTERN_TYPE_SOLID &&
-                (op == CAIRO_OPERATOR_SOURCE ||
-                 (op == CAIRO_OPERATOR_OVER && _cairo_pattern_is_opaque_solid (source)))) {
-            return _cairo_gl_surface_clear (surface,
-                                            &((cairo_solid_pattern_t *) source)->color);
-        }
+		(op == CAIRO_OPERATOR_SOURCE ||
+		 (op == CAIRO_OPERATOR_OVER && _cairo_pattern_is_opaque_solid (source)))) {
+	    return _cairo_gl_surface_clear (surface,
+					    &((cairo_solid_pattern_t *) source)->color);
+	}
     }
 
     return _cairo_compositor_paint (get_compositor (surface), surface,
@@ -1379,16 +1470,16 @@
 }
 
 static cairo_int_status_t
-_cairo_gl_surface_stroke (void			        *surface,
-                          cairo_operator_t		 op,
-                          const cairo_pattern_t	        *source,
-                          const cairo_path_fixed_t	*path,
-                          const cairo_stroke_style_t	*style,
-                          const cairo_matrix_t	        *ctm,
-                          const cairo_matrix_t	        *ctm_inverse,
-                          double			 tolerance,
-                          cairo_antialias_t		 antialias,
-                          const cairo_clip_t		*clip)
+_cairo_gl_surface_stroke (void				*surface,
+			  cairo_operator_t		 op,
+			  const cairo_pattern_t		*source,
+			  const cairo_path_fixed_t	*path,
+			  const cairo_stroke_style_t	*style,
+			  const cairo_matrix_t		*ctm,
+			  const cairo_matrix_t		*ctm_inverse,
+			  double			 tolerance,
+			  cairo_antialias_t		 antialias,
+			  const cairo_clip_t		*clip)
 {
     return _cairo_compositor_stroke (get_compositor (surface), surface,
 				     op, source, path, style,
@@ -1398,13 +1489,13 @@
 
 static cairo_int_status_t
 _cairo_gl_surface_fill (void			*surface,
-                        cairo_operator_t	 op,
-                        const cairo_pattern_t	*source,
-                        const cairo_path_fixed_t*path,
-                        cairo_fill_rule_t	 fill_rule,
-                        double			 tolerance,
-                        cairo_antialias_t	 antialias,
-                        const cairo_clip_t	*clip)
+			cairo_operator_t	 op,
+			const cairo_pattern_t	*source,
+			const cairo_path_fixed_t*path,
+			cairo_fill_rule_t	 fill_rule,
+			double			 tolerance,
+			cairo_antialias_t	 antialias,
+			const cairo_clip_t	*clip)
 {
     return _cairo_compositor_fill (get_compositor (surface), surface,
 				   op, source, path,

Modified: trunk/Build/source/libs/cairo/cairo-src/src/cairo-gl-traps-compositor.c
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/src/cairo-gl-traps-compositor.c	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/src/cairo-gl-traps-compositor.c	2018-10-20 03:19:36 UTC (rev 48952)
@@ -137,13 +137,13 @@
 
     status = _cairo_gl_composite_init (&setup, op, _dst, FALSE);
     if (unlikely (status))
-        goto FAIL;
+	goto FAIL;
 
    _cairo_gl_composite_set_solid_source (&setup, color);
 
     status = _cairo_gl_composite_begin (&setup, &ctx);
     if (unlikely (status))
-        goto FAIL;
+	goto FAIL;
 
     emit_aligned_boxes (ctx, boxes);
     status = _cairo_gl_context_release (ctx, CAIRO_STATUS_SUCCESS);
@@ -173,7 +173,7 @@
 
     status = _cairo_gl_composite_init (&setup, op, _dst, FALSE);
     if (unlikely (status))
-        goto FAIL;
+	goto FAIL;
 
     _cairo_gl_composite_set_source_operand (&setup,
 					    source_to_operand (abstract_src));
@@ -185,7 +185,7 @@
 
     status = _cairo_gl_composite_begin (&setup, &ctx);
     if (unlikely (status))
-        goto FAIL;
+	goto FAIL;
 
     emit_aligned_boxes (ctx, boxes);
     status = _cairo_gl_context_release (ctx, CAIRO_STATUS_SUCCESS);
@@ -215,7 +215,7 @@
 
     status = _cairo_gl_composite_init (&setup, op, _dst, FALSE);
     if (unlikely (status))
-        goto FAIL;
+	goto FAIL;
 
     _cairo_gl_composite_set_source_operand (&setup,
 					    source_to_operand (abstract_src));
@@ -227,7 +227,7 @@
 
     status = _cairo_gl_composite_begin (&setup, &ctx);
     if (unlikely (status))
-        goto FAIL;
+	goto FAIL;
 
     /* XXX clip */
     _cairo_gl_context_emit_rect (ctx, dst_x, dst_y, dst_x+width, dst_y+height);
@@ -303,36 +303,6 @@
 	return image->status;
     }
 
-    /* GLES2 only supports RGB/RGBA when uploading */
-    if (_cairo_gl_get_flavor () == CAIRO_GL_FLAVOR_ES) {
-	cairo_surface_pattern_t pattern;
-	cairo_surface_t *rgba_image;
-
-	/* XXX perform this fixup inside _cairo_gl_draw_image() */
-
-	rgba_image =
-	    _cairo_image_surface_create_with_pixman_format (NULL,
-							    _cairo_is_little_endian () ?  PIXMAN_a8b8g8r8 : PIXMAN_r8g8b8a8,
-							    extents->width,
-							    extents->height,
-							    0);
-	if (unlikely (rgba_image->status))
-	    return rgba_image->status;
-
-	_cairo_pattern_init_for_surface (&pattern, image);
-	status = _cairo_surface_paint (rgba_image, CAIRO_OPERATOR_SOURCE,
-				       &pattern.base, NULL);
-	_cairo_pattern_fini (&pattern.base);
-
-	cairo_surface_destroy (image);
-	image = rgba_image;
-
-	if (unlikely (status)) {
-	    cairo_surface_destroy (image);
-	    return status;
-	}
-    }
-
     mask = _cairo_surface_create_scratch (_dst,
 					  CAIRO_CONTENT_COLOR_ALPHA,
 					  extents->width,
@@ -394,7 +364,7 @@
 
     status = _cairo_gl_composite_init (&setup, op, _dst, FALSE);
     if (unlikely (status))
-        goto FAIL;
+	goto FAIL;
 
     _cairo_gl_composite_set_source_operand (&setup,
 					    source_to_operand (abstract_src));
@@ -405,7 +375,7 @@
 
     status = _cairo_gl_composite_begin (&setup, &ctx);
     if (unlikely (status))
-        goto FAIL;
+	goto FAIL;
 
     /* XXX clip */
     _cairo_gl_context_emit_rect (ctx,
@@ -494,7 +464,7 @@
 
     status = _cairo_gl_composite_init (&setup, op, _dst, FALSE);
     if (unlikely (status))
-        goto FAIL;
+	goto FAIL;
 
     _cairo_gl_composite_set_source_operand (&setup,
 					    source_to_operand (abstract_src));
@@ -503,7 +473,7 @@
 
     status = _cairo_gl_composite_begin (&setup, &ctx);
     if (unlikely (status))
-        goto FAIL;
+	goto FAIL;
 
     /* XXX clip */
     _cairo_gl_context_emit_rect (ctx,
@@ -530,9 +500,10 @@
 const cairo_compositor_t *
 _cairo_gl_traps_compositor_get (void)
 {
+    static cairo_atomic_once_t once = CAIRO_ATOMIC_ONCE_INIT;
     static cairo_traps_compositor_t compositor;
 
-    if (compositor.base.delegate == NULL) {
+    if (_cairo_atomic_init_once_enter(&once)) {
 	_cairo_traps_compositor_init (&compositor, &_cairo_fallback_compositor);
 	compositor.acquire = acquire;
 	compositor.release = release;
@@ -552,6 +523,8 @@
 	compositor.composite_tristrip = composite_tristrip;
 	compositor.check_composite_glyphs = _cairo_gl_check_composite_glyphs;
 	compositor.composite_glyphs = _cairo_gl_composite_glyphs;
+
+	_cairo_atomic_init_once_leave(&once);
     }
 
     return &compositor.base;

Modified: trunk/Build/source/libs/cairo/cairo-src/src/cairo-gl.h
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/src/cairo-gl.h	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/src/cairo-gl.h	2018-10-20 03:19:36 UTC (rev 48952)
@@ -62,7 +62,7 @@
 
 #include "cairo.h"
 
-#if CAIRO_HAS_GL_SURFACE || CAIRO_HAS_GLESV2_SURFACE
+#if CAIRO_HAS_GL_SURFACE || CAIRO_HAS_GLESV2_SURFACE || CAIRO_HAS_GLESV3_SURFACE
 
 CAIRO_BEGIN_DECLS
 

Modified: trunk/Build/source/libs/cairo/cairo-src/src/cairo-glx-context.c
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/src/cairo-glx-context.c	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/src/cairo-glx-context.c	2018-10-20 03:19:36 UTC (rev 48952)
@@ -310,7 +310,7 @@
 	return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH));
 
     if (width <= 0 || height <= 0)
-        return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_SIZE));
+	return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_SIZE));
 
     surface = calloc (1, sizeof (cairo_glx_surface_t));
     if (unlikely (surface == NULL))

Modified: trunk/Build/source/libs/cairo/cairo-src/src/cairo-gstate-private.h
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/src/cairo-gstate-private.h	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/src/cairo-gstate-private.h	2018-10-20 03:19:36 UTC (rev 48952)
@@ -324,6 +324,15 @@
 			    double		height);
 
 cairo_private cairo_status_t
+_cairo_gstate_tag_begin (cairo_gstate_t	*gstate,
+			 const char     *tag_name,
+			 const char     *attributes);
+
+cairo_private cairo_status_t
+_cairo_gstate_tag_end (cairo_gstate_t	*gstate,
+		       const char       *tag_name);
+
+cairo_private cairo_status_t
 _cairo_gstate_set_font_size (cairo_gstate_t *gstate,
 			     double          size);
 

Modified: trunk/Build/source/libs/cairo/cairo-src/src/cairo-gstate.c
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/src/cairo-gstate.c	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/src/cairo-gstate.c	2018-10-20 03:19:36 UTC (rev 48952)
@@ -45,12 +45,6 @@
 #include "cairo-pattern-private.h"
 #include "cairo-traps-private.h"
 
-#if _XOPEN_SOURCE >= 600 || defined (_ISOC99_SOURCE)
-#define ISFINITE(x) isfinite (x)
-#else
-#define ISFINITE(x) ((x) * (x) >= 0.) /* check for NaNs */
-#endif
-
 static cairo_status_t
 _cairo_gstate_init_copy (cairo_gstate_t *gstate, cairo_gstate_t *other);
 
@@ -225,7 +219,7 @@
     cairo_pattern_destroy (gstate->source);
     gstate->source = NULL;
 
-    VG (VALGRIND_MAKE_MEM_NOACCESS (gstate, sizeof (cairo_gstate_t)));
+    VG (VALGRIND_MAKE_MEM_UNDEFINED (gstate, sizeof (cairo_gstate_t)));
 }
 
 /**
@@ -247,7 +241,7 @@
 
     top = *freelist;
     if (top == NULL) {
-	top = malloc (sizeof (cairo_gstate_t));
+	top = _cairo_malloc (sizeof (cairo_gstate_t));
 	if (unlikely (top == NULL))
 	    return _cairo_error (CAIRO_STATUS_NO_MEMORY);
     } else
@@ -1228,6 +1222,7 @@
     _cairo_path_fixed_approximate_stroke_extents (path,
 						  &gstate->stroke_style,
 						  &gstate->ctm,
+						  gstate->target->is_vector,
 						  &extents);
     if (x < extents.x || x > extents.x + extents.width ||
 	y < extents.y || y > extents.y + extents.height)
@@ -1645,6 +1640,65 @@
     return list;
 }
 
+cairo_status_t
+_cairo_gstate_tag_begin (cairo_gstate_t *gstate,
+			 const char *tag_name, const char *attributes)
+{
+    cairo_pattern_union_t source_pattern;
+    cairo_stroke_style_t style;
+    double dash[2];
+    cairo_status_t status;
+    cairo_matrix_t aggregate_transform;
+    cairo_matrix_t aggregate_transform_inverse;
+
+    status = _cairo_gstate_get_pattern_status (gstate->source);
+    if (unlikely (status))
+	return status;
+
+    cairo_matrix_multiply (&aggregate_transform,
+                           &gstate->ctm,
+                           &gstate->target->device_transform);
+    cairo_matrix_multiply (&aggregate_transform_inverse,
+                           &gstate->target->device_transform_inverse,
+                           &gstate->ctm_inverse);
+
+    memcpy (&style, &gstate->stroke_style, sizeof (gstate->stroke_style));
+    if (_cairo_stroke_style_dash_can_approximate (&gstate->stroke_style, &aggregate_transform, gstate->tolerance)) {
+        style.dash = dash;
+        _cairo_stroke_style_dash_approximate (&gstate->stroke_style, &gstate->ctm, gstate->tolerance,
+					      &style.dash_offset,
+					      style.dash,
+					      &style.num_dashes);
+    }
+
+    _cairo_gstate_copy_transformed_source (gstate, &source_pattern.base);
+
+    return _cairo_surface_tag (gstate->target,
+			       TRUE, /* begin */
+			       tag_name,
+			       attributes ? attributes : "",
+			       &source_pattern.base,
+			       &style,
+			       &aggregate_transform,
+			       &aggregate_transform_inverse,
+			       gstate->clip);
+}
+
+cairo_status_t
+_cairo_gstate_tag_end (cairo_gstate_t *gstate,
+		       const char *tag_name)
+{
+    return _cairo_surface_tag (gstate->target,
+			       FALSE, /* begin */
+			       tag_name,
+			       NULL, /* attributes */
+			       NULL, /* source */
+			       NULL, /* stroke_style */
+			       NULL, /* ctm */
+			       NULL, /* ctm_inverse*/
+			       NULL); /* clip */
+}
+
 static void
 _cairo_gstate_unset_scaled_font (cairo_gstate_t *gstate)
 {
@@ -2159,7 +2213,7 @@
 	  *num_transformed_glyphs = 0;
 	  return;
 	}
-	/* XXX We currently drop any glyphs that has its position outside
+	/* XXX We currently drop any glyphs that have their position outside
 	 * of the surface boundaries by a safety margin depending on the
 	 * font scale.  This however can fail in extreme cases where the
 	 * font has really long swashes for example...  We can correctly

Modified: trunk/Build/source/libs/cairo/cairo-src/src/cairo-hash.c
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/src/cairo-hash.c	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/src/cairo-hash.c	2018-10-20 03:19:36 UTC (rev 48952)
@@ -164,7 +164,7 @@
 {
     cairo_hash_table_t *hash_table;
 
-    hash_table = malloc (sizeof (cairo_hash_table_t));
+    hash_table = _cairo_malloc (sizeof (cairo_hash_table_t));
     if (unlikely (hash_table == NULL)) {
 	_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
 	return NULL;

Modified: trunk/Build/source/libs/cairo/cairo-src/src/cairo-image-compositor.c
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/src/cairo-image-compositor.c	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/src/cairo-image-compositor.c	2018-10-20 03:19:36 UTC (rev 48952)
@@ -821,6 +821,18 @@
 }
 
 void
+_cairo_image_compositor_reset_static_data (void)
+{
+    CAIRO_MUTEX_LOCK (_cairo_glyph_cache_mutex);
+
+    if (global_glyph_cache)
+	pixman_glyph_cache_destroy (global_glyph_cache);
+    global_glyph_cache = NULL;
+
+    CAIRO_MUTEX_UNLOCK (_cairo_glyph_cache_mutex);
+}
+
+void
 _cairo_image_scaled_glyph_fini (cairo_scaled_font_t *scaled_font,
 				cairo_scaled_glyph_t *scaled_glyph)
 {
@@ -946,6 +958,11 @@
 }
 #else
 void
+_cairo_image_compositor_reset_static_data (void)
+{
+}
+
+void
 _cairo_image_scaled_glyph_fini (cairo_scaled_font_t *scaled_font,
 				cairo_scaled_glyph_t *scaled_glyph)
 {
@@ -1244,11 +1261,12 @@
 const cairo_compositor_t *
 _cairo_image_traps_compositor_get (void)
 {
+    static cairo_atomic_once_t once = CAIRO_ATOMIC_ONCE_INIT;
     static cairo_traps_compositor_t compositor;
 
-    if (compositor.base.delegate == NULL) {
-	_cairo_traps_compositor_init (&compositor,
-				      &__cairo_no_compositor);
+    if (_cairo_atomic_init_once_enter(&once)) {
+	_cairo_traps_compositor_init(&compositor,
+				     &__cairo_no_compositor);
 	compositor.acquire = acquire;
 	compositor.release = release;
 	compositor.set_clip_region = set_clip_region;
@@ -1269,6 +1287,8 @@
 #endif
 	compositor.check_composite_glyphs = check_composite_glyphs;
 	compositor.composite_glyphs = composite_glyphs;
+
+	_cairo_atomic_init_once_leave(&once);
     }
 
     return &compositor.base;
@@ -1277,9 +1297,10 @@
 const cairo_compositor_t *
 _cairo_image_mask_compositor_get (void)
 {
+    static cairo_atomic_once_t once = CAIRO_ATOMIC_ONCE_INIT;
     static cairo_mask_compositor_t compositor;
 
-    if (compositor.base.delegate == NULL) {
+    if (_cairo_atomic_init_once_enter(&once)) {
 	_cairo_mask_compositor_init (&compositor,
 				     _cairo_image_traps_compositor_get ());
 	compositor.acquire = acquire;
@@ -1296,6 +1317,8 @@
 	compositor.composite_boxes = composite_boxes;
 	compositor.check_composite_glyphs = check_composite_glyphs;
 	compositor.composite_glyphs = composite_glyphs;
+
+	_cairo_atomic_init_once_leave(&once);
     }
 
     return &compositor.base;
@@ -1575,7 +1598,7 @@
     pixman_image_t *src, *mask;
     union {
 	struct fill {
-	    int stride;
+	    ptrdiff_t stride;
 	    uint8_t *data;
 	    uint32_t pixel;
 	} fill;
@@ -1594,7 +1617,7 @@
 	struct finish {
 	    cairo_rectangle_int_t extents;
 	    int src_x, src_y;
-	    int stride;
+	    ptrdiff_t stride;
 	    uint8_t *data;
 	} mask;
     } u;
@@ -1763,7 +1786,7 @@
 	    if (spans[0].coverage) {
 		int len = spans[1].x - spans[0].x;
 		uint16_t *d = (uint16_t*)(r->u.fill.data + r->u.fill.stride*y + spans[0].x*2);
-		while (len--)
+		while (len-- > 0)
 		    *d++ = r->u.fill.pixel;
 	    }
 	    spans++;
@@ -1775,7 +1798,7 @@
 		do {
 		    int len = spans[1].x - spans[0].x;
 		    uint16_t *d = (uint16_t*)(r->u.fill.data + r->u.fill.stride*yy + spans[0].x*2);
-		    while (len--)
+		    while (len-- > 0)
 			*d++ = r->u.fill.pixel;
 		    yy++;
 		} while (--hh);
@@ -1805,7 +1828,7 @@
 				 spans[0].x, y, len, 1, r->u.fill.pixel);
 		} else {
 		    uint32_t *d = (uint32_t*)(r->u.fill.data + r->u.fill.stride*y + spans[0].x*4);
-		    while (len--)
+		    while (len-- > 0)
 			*d++ = r->u.fill.pixel;
 		}
 	    }
@@ -1823,7 +1846,7 @@
 		    do {
 			int len = spans[1].x - spans[0].x;
 			uint32_t *d = (uint32_t*)(r->u.fill.data + r->u.fill.stride*yy + spans[0].x*4);
-			while (len--)
+			while (len-- > 0)
 			    *d++ = r->u.fill.pixel;
 			yy++;
 		    } while (--hh);
@@ -2180,7 +2203,7 @@
 		    uint8_t s = mul8_8(a, r->u.fill.pixel);
 		    uint8_t *dst = d + spans[0].x;
 		    a = ~a;
-		    while (len--) {
+		    while (len-- > 0) {
 			uint8_t t = mul8_8(*dst, a);
 			*dst++ = t + s;
 		    }
@@ -2206,7 +2229,7 @@
 		    do {
 			int len = spans[1].x - spans[0].x;
 			uint8_t *d = r->u.fill.data + r->u.fill.stride*yy + spans[0].x;
-			while (len--) {
+			while (len-- > 0) {
 			    uint8_t t = mul8_8(*d, a);
 			    *d++ = t + s;
 			}
@@ -2266,7 +2289,7 @@
 			do {
 			    int len = spans[1].x - spans[0].x;
 			    uint32_t *d = (uint32_t*)(r->u.fill.data + r->u.fill.stride*yy + spans[0].x*4);
-			    while (len--)
+			    while (len-- > 0)
 				*d++ = r->u.fill.pixel;
 			    yy++;
 			} while (--hh);
@@ -2276,7 +2299,7 @@
 		    do {
 			int len = spans[1].x - spans[0].x;
 			uint32_t *d = (uint32_t *)(r->u.fill.data + r->u.fill.stride*yy + spans[0].x*4);
-			while (len--) {
+			while (len-- > 0) {
 			    *d = lerp8x4 (r->u.fill.pixel, a, *d);
 			    d++;
 			}
@@ -2308,7 +2331,7 @@
 		uint8_t *d = r->u.fill.data + r->u.fill.stride*y + spans[0].x;
 		uint16_t p = (uint16_t)a * r->u.fill.pixel + 0x7f;
 		uint16_t ia = ~a;
-		while (len--) {
+		while (len-- > 0) {
 		    uint16_t t = *d*ia + p;
 		    *d++ = (t + (t>>8)) >> 8;
 		}
@@ -2325,7 +2348,7 @@
 		do {
 		    int len = spans[1].x - spans[0].x;
 		    uint8_t *d = r->u.fill.data + r->u.fill.stride*yy + spans[0].x;
-		    while (len--) {
+		    while (len-- > 0) {
 			uint16_t t = *d*ia + p;
 			*d++ = (t + (t>>8)) >> 8;
 		    }
@@ -2354,7 +2377,7 @@
 	    if (a) {
 		int len = spans[1].x - spans[0].x;
 		uint32_t *d = (uint32_t*)(r->u.fill.data + r->u.fill.stride*y + spans[0].x*4);
-		while (len--) {
+		while (len-- > 0) {
 		    *d = lerp8x4 (r->u.fill.pixel, a, *d);
 		    d++;
 		}
@@ -2369,7 +2392,7 @@
 		do {
 		    int len = spans[1].x - spans[0].x;
 		    uint32_t *d = (uint32_t *)(r->u.fill.data + r->u.fill.stride*yy + spans[0].x*4);
-		    while (len--) {
+		    while (len-- > 0) {
 			*d = lerp8x4 (r->u.fill.pixel, a, *d);
 			d++;
 		    }
@@ -2407,7 +2430,7 @@
 		    else
 			memcpy(d, s, len*4);
 		} else {
-		    while (len--) {
+		    while (len-- > 0) {
 			*d = lerp8x4 (*s, a, *d);
 			s++, d++;
 		    }
@@ -2430,7 +2453,7 @@
 			else
 			    memcpy(d, s, len * 4);
 		    } else {
-			while (len--) {
+			while (len-- > 0) {
 			    *d = lerp8x4 (*s, a, *d);
 			    s++, d++;
 			}
@@ -2911,7 +2934,7 @@
 	/* Create an effectively unbounded mask by repeating the single line */
 	buf = r->_buf;
 	if (width > SZ_BUF) {
-	    buf = malloc (width);
+	    buf = _cairo_malloc (width);
 	    if (unlikely (buf == NULL)) {
 		pixman_image_unref (r->src);
 		return _cairo_error (CAIRO_STATUS_NO_MEMORY);
@@ -3105,10 +3128,11 @@
 const cairo_compositor_t *
 _cairo_image_spans_compositor_get (void)
 {
+    static cairo_atomic_once_t once = CAIRO_ATOMIC_ONCE_INIT;
     static cairo_spans_compositor_t spans;
     static cairo_compositor_t shape;
 
-    if (spans.base.delegate == NULL) {
+    if (_cairo_atomic_init_once_enter(&once)) {
 	_cairo_shape_mask_compositor_init (&shape,
 					   _cairo_image_traps_compositor_get());
 	shape.glyphs = NULL;
@@ -3131,6 +3155,8 @@
 	//spans.check_span_renderer = check_span_renderer;
 	spans.renderer_init = span_renderer_init;
 	spans.renderer_fini = span_renderer_fini;
+
+	_cairo_atomic_init_once_leave(&once);
     }
 
     return &spans.base;

Modified: trunk/Build/source/libs/cairo/cairo-src/src/cairo-image-source.c
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/src/cairo-image-source.c	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/src/cairo-image-source.c	2018-10-20 03:19:36 UTC (rev 48952)
@@ -872,7 +872,7 @@
     size_y = (1 << ysubsample) * ywidth;
 
     *n_values = 4 + size_x + size_y;
-    params = malloc (*n_values * sizeof (pixman_fixed_t));
+    params = _cairo_malloc (*n_values * sizeof (pixman_fixed_t));
     if (!params) return 0;
 
     params[0] = pixman_int_to_fixed (xwidth);
@@ -1077,11 +1077,11 @@
 {
     struct proxy *proxy;
 
-    proxy = malloc (sizeof (*proxy));
+    proxy = _cairo_malloc (sizeof (*proxy));
     if (unlikely (proxy == NULL))
 	return _cairo_surface_create_in_error (CAIRO_STATUS_NO_MEMORY);
 
-    _cairo_surface_init (&proxy->base, &proxy_backend, NULL, image->content);
+    _cairo_surface_init (&proxy->base, &proxy_backend, NULL, image->content, FALSE);
 
     proxy->image = image;
     _cairo_surface_attach_snapshot (source, &proxy->base, NULL);
@@ -1113,10 +1113,12 @@
 {
     cairo_surface_t *source, *clone, *proxy;
     cairo_rectangle_int_t limit;
+    cairo_rectangle_int_t src_limit;
     pixman_image_t *pixman_image;
     cairo_status_t status;
     cairo_extend_t extend;
     cairo_matrix_t *m, matrix;
+    double sx = 1.0, sy = 1.0;
     int tx = 0, ty = 0;
 
     TRACE ((stderr, "%s\n", __FUNCTION__));
@@ -1124,34 +1126,38 @@
     *ix = *iy = 0;
 
     source = _cairo_pattern_get_source (pattern, &limit);
+    src_limit = limit;
 
     extend = pattern->base.extend;
     if (_cairo_rectangle_contains_rectangle (&limit, sample))
 	extend = CAIRO_EXTEND_NONE;
+
     if (extend == CAIRO_EXTEND_NONE) {
 	if (! _cairo_rectangle_intersect (&limit, sample))
 	    return _pixman_transparent_image ();
+    }
 
-	if (! _cairo_matrix_is_identity (&pattern->base.matrix)) {
-	    double x1, y1, x2, y2;
+    if (! _cairo_matrix_is_identity (&pattern->base.matrix)) {
+	double x1, y1, x2, y2;
 
-	    matrix = pattern->base.matrix;
-	    status = cairo_matrix_invert (&matrix);
-	    assert (status == CAIRO_STATUS_SUCCESS);
+	matrix = pattern->base.matrix;
+	status = cairo_matrix_invert (&matrix);
+	assert (status == CAIRO_STATUS_SUCCESS);
 
-	    x1 = limit.x;
-	    y1 = limit.y;
-	    x2 = limit.x + limit.width;
-	    y2 = limit.y + limit.height;
+	x1 = limit.x;
+	y1 = limit.y;
+	x2 = limit.x + limit.width;
+	y2 = limit.y + limit.height;
 
-	    _cairo_matrix_transform_bounding_box (&matrix,
-						  &x1, &y1, &x2, &y2, NULL);
+	_cairo_matrix_transform_bounding_box (&matrix,
+					      &x1, &y1, &x2, &y2, NULL);
 
-	    limit.x = floor (x1);
-	    limit.y = floor (y1);
-	    limit.width  = ceil (x2) - limit.x;
-	    limit.height = ceil (y2) - limit.y;
-	}
+	limit.x = floor (x1);
+	limit.y = floor (y1);
+	limit.width  = ceil (x2) - limit.x;
+	limit.height = ceil (y2) - limit.y;
+	sx = (double)src_limit.width / limit.width;
+	sy = (double)src_limit.height / limit.height;
     }
     tx = limit.x;
     ty = limit.y;
@@ -1183,7 +1189,9 @@
 	    cairo_matrix_translate (&matrix, tx, ty);
 	m = &matrix;
     } else {
-	/* XXX extract scale factor for repeating patterns */
+	cairo_matrix_init_scale (&matrix, sx, sy);
+	cairo_matrix_translate (&matrix, src_limit.x/sx, src_limit.y/sy);
+	m = &matrix;
     }
 
     /* Handle recursion by returning future reads from the current image */
@@ -1199,11 +1207,22 @@
     pixman_image = pixman_image_ref (((cairo_image_surface_t *)clone)->pixman_image);
     cairo_surface_destroy (clone);
 
-    *ix = -limit.x;
-    *iy = -limit.y;
-    if (extend != CAIRO_EXTEND_NONE) {
+    if (extend == CAIRO_EXTEND_NONE) {
+	*ix = -limit.x;
+	*iy = -limit.y;
+    } else {
+	cairo_pattern_union_t tmp_pattern;
+	_cairo_pattern_init_static_copy (&tmp_pattern.base, &pattern->base);
+	matrix = pattern->base.matrix;
+	status = cairo_matrix_invert(&matrix);
+	assert (status == CAIRO_STATUS_SUCCESS);
+	cairo_matrix_translate (&matrix, src_limit.x, src_limit.y);
+	cairo_matrix_scale (&matrix, sx, sy);
+	status = cairo_matrix_invert(&matrix);
+	assert (status == CAIRO_STATUS_SUCCESS);
+	cairo_pattern_set_matrix (&tmp_pattern.base, &matrix);
 	if (! _pixman_image_set_properties (pixman_image,
-					    &pattern->base, extents,
+					    &tmp_pattern.base, extents,
 					    ix, iy)) {
 	    pixman_image_unref (pixman_image);
 	    pixman_image= NULL;
@@ -1388,7 +1407,7 @@
 	    return NULL;
 	}
 
-	cleanup = malloc (sizeof (*cleanup));
+	cleanup = _cairo_malloc (sizeof (*cleanup));
 	if (unlikely (cleanup == NULL)) {
 	    _cairo_surface_release_source_image (pattern->surface, image, extra);
 	    pixman_image_unref (pixman_image);
@@ -1479,7 +1498,7 @@
 	return NULL;
     }
 
-    cleanup = malloc (sizeof (*cleanup));
+    cleanup = _cairo_malloc (sizeof (*cleanup));
     if (unlikely (cleanup == NULL)) {
 	pixman_image_unref (pixman_image);
 	_cairo_surface_release_source_image (surface, image, extra);
@@ -1575,7 +1594,7 @@
 
     TRACE ((stderr, "%s\n", __FUNCTION__));
 
-    source = malloc (sizeof (cairo_image_source_t));
+    source = _cairo_malloc (sizeof (cairo_image_source_t));
     if (unlikely (source == NULL))
 	return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
 
@@ -1592,7 +1611,8 @@
     _cairo_surface_init (&source->base,
 			 &_cairo_image_source_backend,
 			 NULL, /* device */
-			 CAIRO_CONTENT_COLOR_ALPHA);
+			 CAIRO_CONTENT_COLOR_ALPHA,
+			 FALSE); /* is_vector */
 
     source->is_opaque_solid =
 	pattern == NULL || _cairo_pattern_is_opaque_solid (pattern);

Modified: trunk/Build/source/libs/cairo/cairo-src/src/cairo-image-surface-private.h
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/src/cairo-image-surface-private.h	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/src/cairo-image-surface-private.h	2018-10-20 03:19:36 UTC (rev 48952)
@@ -40,6 +40,7 @@
 
 #include "cairo-surface-private.h"
 
+#include <stddef.h>
 #include <pixman.h>
 
 CAIRO_BEGIN_DECLS
@@ -71,7 +72,7 @@
 
     int width;
     int height;
-    int stride;
+    ptrdiff_t stride;
     int depth;
 
     unsigned owns_data : 1;

Modified: trunk/Build/source/libs/cairo/cairo-src/src/cairo-image-surface.c
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/src/cairo-image-surface.c	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/src/cairo-image-surface.c	2018-10-20 03:19:36 UTC (rev 48952)
@@ -52,6 +52,7 @@
 #include "cairo-recording-surface-private.h"
 #include "cairo-region-private.h"
 #include "cairo-scaled-font-private.h"
+#include "cairo-surface-snapshot-inline.h"
 #include "cairo-surface-snapshot-private.h"
 #include "cairo-surface-subsurface-private.h"
 
@@ -181,7 +182,7 @@
 {
     cairo_image_surface_t *surface;
 
-    surface = malloc (sizeof (cairo_image_surface_t));
+    surface = _cairo_malloc (sizeof (cairo_image_surface_t));
     if (unlikely (surface == NULL))
 	return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
 
@@ -188,7 +189,8 @@
     _cairo_surface_init (&surface->base,
 			 &_cairo_image_surface_backend,
 			 NULL, /* device */
-			 _cairo_content_from_pixman_format (pixman_format));
+			 _cairo_content_from_pixman_format (pixman_format),
+			 FALSE); /* is_vector */
 
     _cairo_image_surface_init (surface, pixman_image, pixman_format);
 
@@ -369,8 +371,8 @@
  * @height: height of the surface, in pixels
  *
  * Creates an image surface of the specified format and
- * dimensions. Initially the surface contents are all
- * 0. (Specifically, within each pixel, each color or alpha channel
+ * dimensions. Initially the surface contents are set to 0.
+ * (Specifically, within each pixel, each color or alpha channel
  * belonging to format will be 0. The contents of bits within a pixel,
  * but not belonging to the given format are undefined).
  *
@@ -1152,23 +1154,21 @@
     return (cairo_image_surface_t *) _cairo_surface_create_in_error (status);
 }
 
-cairo_image_transparency_t
-_cairo_image_analyze_transparency (cairo_image_surface_t *image)
+static cairo_image_transparency_t
+_cairo_image_compute_transparency (cairo_image_surface_t *image)
 {
     int x, y;
+    cairo_image_transparency_t transparency;
 
-    if (image->transparency != CAIRO_IMAGE_UNKNOWN)
-	return image->transparency;
-
     if ((image->base.content & CAIRO_CONTENT_ALPHA) == 0)
-	return image->transparency = CAIRO_IMAGE_IS_OPAQUE;
+	return CAIRO_IMAGE_IS_OPAQUE;
 
     if (image->base.is_clear)
-	return image->transparency = CAIRO_IMAGE_HAS_BILEVEL_ALPHA;
+	return CAIRO_IMAGE_HAS_BILEVEL_ALPHA;
 
     if ((image->base.content & CAIRO_CONTENT_COLOR) == 0) {
 	if (image->format == CAIRO_FORMAT_A1) {
-	    return image->transparency = CAIRO_IMAGE_HAS_BILEVEL_ALPHA;
+	    return CAIRO_IMAGE_HAS_BILEVEL_ALPHA;
 	} else if (image->format == CAIRO_FORMAT_A8) {
 	    for (y = 0; y < image->height; y++) {
 		uint8_t *alpha = (uint8_t *) (image->data + y * image->stride);
@@ -1175,24 +1175,23 @@
 
 		for (x = 0; x < image->width; x++, alpha++) {
 		    if (*alpha > 0 && *alpha < 255)
-			return image->transparency = CAIRO_IMAGE_HAS_ALPHA;
+			return CAIRO_IMAGE_HAS_ALPHA;
 		}
 	    }
-	    return image->transparency = CAIRO_IMAGE_HAS_BILEVEL_ALPHA;
+	    return CAIRO_IMAGE_HAS_BILEVEL_ALPHA;
 	} else {
-	    return image->transparency = CAIRO_IMAGE_HAS_ALPHA;
+	    return CAIRO_IMAGE_HAS_ALPHA;
 	}
     }
 
     if (image->format == CAIRO_FORMAT_RGB16_565) {
-	image->transparency = CAIRO_IMAGE_IS_OPAQUE;
 	return CAIRO_IMAGE_IS_OPAQUE;
     }
 
     if (image->format != CAIRO_FORMAT_ARGB32)
-	return image->transparency = CAIRO_IMAGE_HAS_ALPHA;
+	return CAIRO_IMAGE_HAS_ALPHA;
 
-    image->transparency = CAIRO_IMAGE_IS_OPAQUE;
+    transparency = CAIRO_IMAGE_IS_OPAQUE;
     for (y = 0; y < image->height; y++) {
 	uint32_t *pixel = (uint32_t *) (image->data + y * image->stride);
 
@@ -1199,32 +1198,43 @@
 	for (x = 0; x < image->width; x++, pixel++) {
 	    int a = (*pixel & 0xff000000) >> 24;
 	    if (a > 0 && a < 255) {
-		return image->transparency = CAIRO_IMAGE_HAS_ALPHA;
+		return CAIRO_IMAGE_HAS_ALPHA;
 	    } else if (a == 0) {
-		image->transparency = CAIRO_IMAGE_HAS_BILEVEL_ALPHA;
+		transparency = CAIRO_IMAGE_HAS_BILEVEL_ALPHA;
 	    }
 	}
     }
 
-    return image->transparency;
+    return transparency;
 }
 
-cairo_image_color_t
-_cairo_image_analyze_color (cairo_image_surface_t      *image)
+cairo_image_transparency_t
+_cairo_image_analyze_transparency (cairo_image_surface_t *image)
 {
+    if (_cairo_surface_is_snapshot (&image->base)) {
+	if (image->transparency == CAIRO_IMAGE_UNKNOWN)
+	    image->transparency = _cairo_image_compute_transparency (image);
+
+	return image->transparency;
+    }
+
+    return _cairo_image_compute_transparency (image);
+}
+
+static cairo_image_color_t
+_cairo_image_compute_color (cairo_image_surface_t      *image)
+{
     int x, y;
+    cairo_image_color_t color;
 
-    if (image->color != CAIRO_IMAGE_UNKNOWN_COLOR)
-	return image->color;
-
     if (image->format == CAIRO_FORMAT_A1)
-	return image->color = CAIRO_IMAGE_IS_MONOCHROME;
+	return CAIRO_IMAGE_IS_MONOCHROME;
 
     if (image->format == CAIRO_FORMAT_A8)
-	return image->color = CAIRO_IMAGE_IS_GRAYSCALE;
+	return CAIRO_IMAGE_IS_GRAYSCALE;
 
     if (image->format == CAIRO_FORMAT_ARGB32) {
-	image->color = CAIRO_IMAGE_IS_MONOCHROME;
+	color = CAIRO_IMAGE_IS_MONOCHROME;
 	for (y = 0; y < image->height; y++) {
 	    uint32_t *pixel = (uint32_t *) (image->data + y * image->stride);
 
@@ -1241,16 +1251,16 @@
 		    b = (b * 255 + a / 2) / a;
 		}
 		if (!(r == g && g == b))
-		    return image->color = CAIRO_IMAGE_IS_COLOR;
+		    return CAIRO_IMAGE_IS_COLOR;
 		else if (r > 0 && r < 255)
-		    image->color = CAIRO_IMAGE_IS_GRAYSCALE;
+		    color = CAIRO_IMAGE_IS_GRAYSCALE;
 	    }
 	}
-	return image->color;
+	return color;
     }
 
     if (image->format == CAIRO_FORMAT_RGB24) {
-	image->color = CAIRO_IMAGE_IS_MONOCHROME;
+	color = CAIRO_IMAGE_IS_MONOCHROME;
 	for (y = 0; y < image->height; y++) {
 	    uint32_t *pixel = (uint32_t *) (image->data + y * image->stride);
 
@@ -1259,15 +1269,28 @@
 		int g = (*pixel & 0x0000ff00) >>  8;
 		int b = (*pixel & 0x000000ff);
 		if (!(r == g && g == b))
-		    return image->color = CAIRO_IMAGE_IS_COLOR;
+		    return CAIRO_IMAGE_IS_COLOR;
 		else if (r > 0 && r < 255)
-		    image->color = CAIRO_IMAGE_IS_GRAYSCALE;
+		    color = CAIRO_IMAGE_IS_GRAYSCALE;
 	    }
 	}
+	return color;
+    }
+
+    return CAIRO_IMAGE_IS_COLOR;
+}
+
+cairo_image_color_t
+_cairo_image_analyze_color (cairo_image_surface_t      *image)
+{
+    if (_cairo_surface_is_snapshot (&image->base)) {
+	if (image->color == CAIRO_IMAGE_UNKNOWN_COLOR)
+	    image->color = _cairo_image_compute_color (image);
+
 	return image->color;
     }
 
-    return image->color = CAIRO_IMAGE_IS_COLOR;
+    return _cairo_image_compute_color (image);
 }
 
 cairo_image_surface_t *

Modified: trunk/Build/source/libs/cairo/cairo-src/src/cairo-line.c
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/src/cairo-line.c	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/src/cairo-line.c	2018-10-20 03:19:36 UTC (rev 48952)
@@ -110,9 +110,9 @@
      * should prevent that before the tessellation algorithm
      * begins.
      */
-    int32_t dx;
-    int32_t adx, ady;
-    int32_t bdx, bdy;
+    int32_t dx = 0;
+    int32_t adx = 0, ady = 0;
+    int32_t bdx = 0, bdy = 0;
     enum {
        HAVE_NONE    = 0x0,
        HAVE_DX      = 0x1,
@@ -218,7 +218,7 @@
        HAVE_BX      = 0x2,
        HAVE_BOTH    = HAVE_AX | HAVE_BX
     } have_ax_bx = HAVE_BOTH;
-    int32_t ax, bx;
+    int32_t ax = 0, bx = 0;
 
     if (y == a->p1.y)
 	ax = a->p1.x;

Modified: trunk/Build/source/libs/cairo/cairo-src/src/cairo-lzw.c
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/src/cairo-lzw.c	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/src/cairo-lzw.c	2018-10-20 03:19:36 UTC (rev 48952)
@@ -73,7 +73,7 @@
     buf->pending = 0;
     buf->pending_bits = 0;
 
-    buf->data = malloc (size);
+    buf->data = _cairo_malloc (size);
     if (unlikely (buf->data == NULL)) {
 	buf->data_size = 0;
 	buf->status = _cairo_error (CAIRO_STATUS_NO_MEMORY);

Modified: trunk/Build/source/libs/cairo/cairo-src/src/cairo-malloc-private.h
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/src/cairo-malloc-private.h	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/src/cairo-malloc-private.h	2018-10-20 03:19:36 UTC (rev 48952)
@@ -60,7 +60,7 @@
  **/
 
 #define _cairo_malloc(size) \
-   ((size) ? malloc((unsigned) (size)) : NULL)
+   ((size) > 0 ? malloc((unsigned) (size)) : NULL)
 
 /**
  * _cairo_malloc_ab:

Modified: trunk/Build/source/libs/cairo/cairo-src/src/cairo-matrix.c
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/src/cairo-matrix.c	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/src/cairo-matrix.c	2018-10-20 03:19:36 UTC (rev 48952)
@@ -40,12 +40,6 @@
 
 #define PIXMAN_MAX_INT ((pixman_fixed_1 >> 1) - pixman_fixed_e) /* need to ensure deltas also fit */
 
-#if _XOPEN_SOURCE >= 600 || defined (_ISOC99_SOURCE)
-#define ISFINITE(x) isfinite (x)
-#else
-#define ISFINITE(x) ((x) * (x) >= 0.) /* check for NaNs */
-#endif
-
 /**
  * SECTION:cairo-matrix
  * @Title: cairo_matrix_t

Modified: trunk/Build/source/libs/cairo/cairo-src/src/cairo-mempool.c
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/src/cairo-mempool.c	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/src/cairo-mempool.c	2018-10-20 03:19:36 UTC (rev 48952)
@@ -316,7 +316,7 @@
     for (i = 0; i < ARRAY_LENGTH (pool->free); i++)
 	cairo_list_init (&pool->free[i]);
 
-    pool->map = malloc ((num_blocks + 7) >> 3);
+    pool->map = _cairo_malloc ((num_blocks + 7) >> 3);
     if (pool->map == NULL) {
 	free (pool->blocks);
 	return _cairo_error (CAIRO_STATUS_NO_MEMORY);

Modified: trunk/Build/source/libs/cairo/cairo-src/src/cairo-mesh-pattern-rasterizer.c
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/src/cairo-mesh-pattern-rasterizer.c	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/src/cairo-mesh-pattern-rasterizer.c	2018-10-20 03:19:36 UTC (rev 48952)
@@ -470,7 +470,7 @@
 	tg += tg >> 16;
 	tb += tb >> 16;
 
-	*((uint32_t*) (data + y*stride + 4*x)) = ((ta << 16) & 0xff000000) |
+	*((uint32_t*) (data + y*(ptrdiff_t)stride + 4*x)) = ((ta << 16) & 0xff000000) |
 	    ((tr >> 8) & 0xff0000) | ((tg >> 16) & 0xff00) | (tb >> 24);
     }
 }

Modified: trunk/Build/source/libs/cairo/cairo-src/src/cairo-misc.c
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/src/cairo-misc.c	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/src/cairo-misc.c	2018-10-20 03:19:36 UTC (rev 48952)
@@ -41,6 +41,13 @@
 #include "cairoint.h"
 #include "cairo-error-private.h"
 
+#include <stdio.h>
+#include <errno.h>
+#include <locale.h>
+#ifdef HAVE_XLOCALE_H
+#include <xlocale.h>
+#endif
+
 COMPILE_TIME_ASSERT ((int)CAIRO_STATUS_LAST_STATUS < (int)CAIRO_INT_STATUS_UNSUPPORTED);
 COMPILE_TIME_ASSERT (CAIRO_INT_STATUS_LAST_STATUS <= 127);
 
@@ -49,7 +56,7 @@
  * @Title: Error handling
  * @Short_Description: Decoding cairo's status
  * @See_Also: cairo_status(), cairo_surface_status(), cairo_pattern_status(),
- *            cairo_font_face_status(), cairo_scaled_font_status(), 
+ *            cairo_font_face_status(), cairo_scaled_font_status(),
  *            cairo_region_status()
  *
  * Cairo uses a single status type to represent all kinds of errors.  A status
@@ -158,6 +165,14 @@
 	return "the target device has been finished";
     case CAIRO_STATUS_JBIG2_GLOBAL_MISSING:
 	return "CAIRO_MIME_TYPE_JBIG2_GLOBAL_ID used but no CAIRO_MIME_TYPE_JBIG2_GLOBAL data provided";
+    case CAIRO_STATUS_PNG_ERROR:
+	return "error occurred in libpng while reading from or writing to a PNG file";
+    case CAIRO_STATUS_FREETYPE_ERROR:
+	return "error occurred in libfreetype";
+    case CAIRO_STATUS_WIN32_GDI_ERROR:
+	return "error occurred in the Windows Graphics Device Interface";
+    case CAIRO_STATUS_TAG_ERROR:
+	return "invalid tag name, attributes, or nesting";
     default:
     case CAIRO_STATUS_LAST_STATUS:
 	return "<unknown error status>";
@@ -763,7 +778,7 @@
 # include <locale.h>
 
 const char *
-cairo_get_locale_decimal_point (void)
+_cairo_get_locale_decimal_point (void)
 {
     struct lconv *locale_data = localeconv ();
     return locale_data->decimal_point;
@@ -772,12 +787,160 @@
 #else
 /* Android's Bionic libc doesn't provide decimal_point */
 const char *
-cairo_get_locale_decimal_point (void)
+_cairo_get_locale_decimal_point (void)
 {
     return ".";
 }
 #endif
 
+#if defined (HAVE_NEWLOCALE) && defined (HAVE_STRTOD_L)
+
+static locale_t C_locale;
+
+static locale_t
+get_C_locale (void)
+{
+    locale_t C;
+
+retry:
+    C = (locale_t) _cairo_atomic_ptr_get ((void **) &C_locale);
+
+    if (unlikely (!C)) {
+        C = newlocale (LC_ALL_MASK, "C", NULL);
+
+        if (!_cairo_atomic_ptr_cmpxchg ((void **) &C_locale, NULL, C)) {
+            freelocale (C_locale);
+            goto retry;
+        }
+    }
+
+    return C;
+}
+
+double
+_cairo_strtod (const char *nptr, char **endptr)
+{
+    return strtod_l (nptr, endptr, get_C_locale ());
+}
+
+#else
+
+/* strtod replacement that ignores locale and only accepts decimal points */
+double
+_cairo_strtod (const char *nptr, char **endptr)
+{
+    const char *decimal_point;
+    int decimal_point_len;
+    const char *p;
+    char buf[100];
+    char *bufptr;
+    char *bufend = buf + sizeof(buf) - 1;
+    double value;
+    char *end;
+    int delta;
+    cairo_bool_t have_dp;
+
+    decimal_point = _cairo_get_locale_decimal_point ();
+    decimal_point_len = strlen (decimal_point);
+    assert (decimal_point_len != 0);
+
+    p = nptr;
+    bufptr = buf;
+    delta = 0;
+    have_dp = FALSE;
+    while (*p && _cairo_isspace (*p)) {
+	p++;
+	delta++;
+    }
+
+    while (*p && (bufptr + decimal_point_len < bufend)) {
+	if (_cairo_isdigit (*p)) {
+	    *bufptr++ = *p;
+	} else if (*p == '.') {
+	    if (have_dp)
+		break;
+	    strncpy (bufptr, decimal_point, decimal_point_len);
+	    bufptr += decimal_point_len;
+	    delta -= decimal_point_len - 1;
+	    have_dp = TRUE;
+	} else {
+	    break;
+	}
+	p++;
+    }
+    *bufptr = 0;
+
+    value = strtod (buf, &end);
+    if (endptr) {
+	if (end == buf)
+	    *endptr = (char*)(nptr);
+	else
+	    *endptr = (char*)(nptr + (end - buf) + delta);
+    }
+
+    return value;
+}
+#endif
+
+/**
+ * _cairo_fopen:
+ * @filename: filename to open
+ * @mode: mode string with which to open the file
+ * @file_out: reference to file handle
+ *
+ * Exactly like the C library function, but possibly doing encoding
+ * conversion on the filename. On all platforms, the filename is
+ * passed directly to the system, but on Windows, the filename is
+ * interpreted as UTF-8, rather than in a codepage that would depend
+ * on system settings.
+ *
+ * Return value: CAIRO_STATUS_SUCCESS when the filename was converted
+ * successfully to the native encoding, or the error reported by
+ * _cairo_utf8_to_utf16 otherwise. To check if the file handle could
+ * be obtained, dereference file_out and compare its value against
+ * NULL
+ **/
+cairo_status_t
+_cairo_fopen (const char *filename, const char *mode, FILE **file_out)
+{
+    FILE *result;
+#ifdef _WIN32 /* also defined on x86_64 */
+    uint16_t *filename_w;
+    uint16_t *mode_w;
+    cairo_status_t status;
+
+    *file_out = NULL;
+
+    if (filename == NULL || mode == NULL) {
+	errno = EINVAL;
+	return CAIRO_STATUS_SUCCESS;
+    }
+
+    if ((status = _cairo_utf8_to_utf16 (filename, -1, &filename_w, NULL)) != CAIRO_STATUS_SUCCESS) {
+	errno = EINVAL;
+	return status;
+    }
+
+    if ((status = _cairo_utf8_to_utf16 (mode, -1, &mode_w, NULL)) != CAIRO_STATUS_SUCCESS) {
+	free (filename_w);
+	errno = EINVAL;
+	return status;
+    }
+
+    result = _wfopen(filename_w, mode_w);
+
+    free (filename_w);
+    free (mode_w);
+
+#else /* Use fopen directly */
+    result = fopen (filename, mode);
+#endif
+
+    *file_out = result;
+
+    return CAIRO_STATUS_SUCCESS;
+}
+
 #ifdef _WIN32
 
 #define WIN32_LEAN_AND_MEAN
@@ -854,13 +1017,13 @@
 
 static cairo_hash_table_t *_cairo_intern_string_ht;
 
-static unsigned long
-_intern_string_hash (const char *str, int len)
+unsigned long
+_cairo_string_hash (const char *str, int len)
 {
     const signed char *p = (const signed char *) str;
     unsigned int h = *p;
 
-    for (p += 1; --len; p++)
+    for (p += 1; len > 0; len--, p++)
 	h = (h << 5) - h + *p;
 
     return h;
@@ -890,7 +1053,7 @@
 
     if (len < 0)
 	len = strlen (str);
-    tmpl.hash_entry.hash = _intern_string_hash (str, len);
+    tmpl.hash_entry.hash = _cairo_string_hash (str, len);
     tmpl.len = len;
     tmpl.string = (char *) str;
 
@@ -906,7 +1069,7 @@
     istring = _cairo_hash_table_lookup (_cairo_intern_string_ht,
 					&tmpl.hash_entry);
     if (istring == NULL) {
-	istring = malloc (sizeof (cairo_intern_string_t) + len + 1);
+	istring = _cairo_malloc (sizeof (cairo_intern_string_t) + len + 1);
 	if (likely (istring != NULL)) {
 	    istring->hash_entry.hash = tmpl.hash_entry.hash;
 	    istring->len = tmpl.len;

Modified: trunk/Build/source/libs/cairo/cairo-src/src/cairo-mono-scan-converter.c
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/src/cairo-mono-scan-converter.c	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/src/cairo-mono-scan-converter.c	2018-10-20 03:19:36 UTC (rev 48952)
@@ -587,7 +587,7 @@
     cairo_mono_scan_converter_t *self;
     cairo_status_t status;
 
-    self = malloc (sizeof(struct _cairo_mono_scan_converter));
+    self = _cairo_malloc (sizeof(struct _cairo_mono_scan_converter));
     if (unlikely (self == NULL)) {
 	status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
 	goto bail_nomem;

Modified: trunk/Build/source/libs/cairo/cairo-src/src/cairo-os2-surface.c
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/src/cairo-os2-surface.c	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/src/cairo-os2-surface.c	2018-10-20 03:19:36 UTC (rev 48952)
@@ -198,7 +198,7 @@
         return NULL;
 #else
     /* Clear the malloc'd buffer the way DosAllocMem() does. */
-    buffer = malloc (nbytes);
+    buffer = _cairo_malloc (nbytes);
     if (buffer) {
         memset (buffer, 0, nbytes);
     }
@@ -718,7 +718,7 @@
     }
 
     /* Allocate an OS/2 surface structure. */
-    local_os2_surface = (cairo_os2_surface_t *) malloc (sizeof (cairo_os2_surface_t));
+    local_os2_surface = (cairo_os2_surface_t *) _cairo_malloc (sizeof (cairo_os2_surface_t));
     if (!local_os2_surface) {
         status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
         goto error_exit;
@@ -780,7 +780,8 @@
     _cairo_surface_init (&local_os2_surface->base,
                          &cairo_os2_surface_backend,
                          NULL, /* device */
-                         _cairo_content_from_format (CAIRO_FORMAT_ARGB32));
+                         _cairo_content_from_format (CAIRO_FORMAT_ARGB32),
+			 FALSE); /* is_vector */
 
     /* Successful exit */
     return (cairo_surface_t *)local_os2_surface;

Modified: trunk/Build/source/libs/cairo/cairo-src/src/cairo-output-stream.c
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/src/cairo-output-stream.c	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/src/cairo-output-stream.c	2018-10-20 03:19:36 UTC (rev 48952)
@@ -147,7 +147,7 @@
 {
     cairo_output_stream_with_closure_t *stream;
 
-    stream = malloc (sizeof (cairo_output_stream_with_closure_t));
+    stream = _cairo_malloc (sizeof (cairo_output_stream_with_closure_t));
     if (unlikely (stream == NULL)) {
 	_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
 	return (cairo_output_stream_t *) &_cairo_output_stream_nil;
@@ -173,7 +173,7 @@
     if (status == CAIRO_STATUS_WRITE_ERROR)
 	return (cairo_output_stream_t *) &_cairo_output_stream_nil_write_error;
 
-    stream = malloc (sizeof (cairo_output_stream_t));
+    stream = _cairo_malloc (sizeof (cairo_output_stream_t));
     if (unlikely (stream == NULL)) {
 	_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
 	return (cairo_output_stream_t *) &_cairo_output_stream_nil;
@@ -293,7 +293,7 @@
 
 /* Format a double in a locale independent way and trim trailing
  * zeros.  Based on code from Alex Larson <alexl at redhat.com>.
- * http://mail.gnome.org/archives/gtk-devel-list/2001-October/msg00087.html
+ * https://mail.gnome.org/archives/gtk-devel-list/2001-October/msg00087.html
  *
  * The code in the patch is copyright Red Hat, Inc under the LGPL, but
  * has been relicensed under the LGPL/MPL dual license for inclusion
@@ -312,7 +312,7 @@
     if (d == 0.0)
 	d = 0.0;
 
-    decimal_point = cairo_get_locale_decimal_point ();
+    decimal_point = _cairo_get_locale_decimal_point ();
     decimal_point_len = strlen (decimal_point);
 
     assert (decimal_point_len != 0);
@@ -639,7 +639,7 @@
 	return (cairo_output_stream_t *) &_cairo_output_stream_nil_write_error;
     }
 
-    stream = malloc (sizeof *stream);
+    stream = _cairo_malloc (sizeof *stream);
     if (unlikely (stream == NULL)) {
 	_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
 	return (cairo_output_stream_t *) &_cairo_output_stream_nil;
@@ -657,11 +657,16 @@
 {
     stdio_stream_t *stream;
     FILE *file;
+    cairo_status_t status;
 
     if (filename == NULL)
 	return _cairo_null_stream_create ();
 
-    file = fopen (filename, "wb");
+    status = _cairo_fopen (filename, "wb", &file);
+
+    if (status != CAIRO_STATUS_SUCCESS)
+	return _cairo_output_stream_create_in_error (status);
+
     if (file == NULL) {
 	switch (errno) {
 	case ENOMEM:
@@ -673,7 +678,7 @@
 	}
     }
 
-    stream = malloc (sizeof *stream);
+    stream = _cairo_malloc (sizeof *stream);
     if (unlikely (stream == NULL)) {
 	fclose (file);
 	_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
@@ -717,7 +722,7 @@
 {
     memory_stream_t *stream;
 
-    stream = malloc (sizeof *stream);
+    stream = _cairo_malloc (sizeof *stream);
     if (unlikely (stream == NULL)) {
 	_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
 	return (cairo_output_stream_t *) &_cairo_output_stream_nil;
@@ -744,7 +749,7 @@
     stream = (memory_stream_t *) abstract_stream;
 
     *length_out = _cairo_array_num_elements (&stream->array);
-    *data_out = malloc (*length_out);
+    *data_out = _cairo_malloc (*length_out);
     if (unlikely (*data_out == NULL)) {
 	status = _cairo_output_stream_destroy (abstract_stream);
 	assert (status == CAIRO_STATUS_SUCCESS);
@@ -794,7 +799,7 @@
 {
     cairo_output_stream_t *stream;
 
-    stream = malloc (sizeof *stream);
+    stream = _cairo_malloc (sizeof *stream);
     if (unlikely (stream == NULL)) {
 	_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
 	return (cairo_output_stream_t *) &_cairo_output_stream_nil;

Modified: trunk/Build/source/libs/cairo/cairo-src/src/cairo-paginated-private.h
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/src/cairo-paginated-private.h	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/src/cairo-paginated-private.h	2018-10-20 03:19:36 UTC (rev 48952)
@@ -56,7 +56,7 @@
      * CAIRO_PAGINATED_MODE_RENDER. See more details in the
      * documentation for _cairo_paginated_surface_create below.
      */
-    void
+    cairo_warn cairo_int_status_t
     (*set_paginated_mode)	(void			*surface,
 				 cairo_paginated_mode_t	 mode);
 
@@ -77,7 +77,23 @@
 				     cairo_bool_t    fallbacks_required);
 
     cairo_bool_t
-    (*supports_fine_grained_fallbacks) (void		    *surface);
+    (*supports_fine_grained_fallbacks) (void	    *surface);
+
+    /* Optional. Indicates whether the page requires a thumbnail image to be
+     * supplied. If a thumbnail is required, set width, heigh to size required
+     * and return TRUE.
+     */
+    cairo_bool_t
+    (*requires_thumbnail_image) (void	*surface,
+				 int    *width,
+				 int    *height);
+
+    /* If thumbbail image requested, this function will be called before
+     * _show_page().
+     */
+    cairo_warn cairo_int_status_t
+    (*set_thumbnail_image) (void	          *surface,
+			    cairo_image_surface_t *image);
 };
 
 /* A #cairo_paginated_surface_t provides a very convenient wrapper that

Modified: trunk/Build/source/libs/cairo/cairo-src/src/cairo-paginated-surface.c
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/src/cairo-paginated-surface.c	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/src/cairo-paginated-surface.c	2018-10-20 03:19:36 UTC (rev 48952)
@@ -98,7 +98,7 @@
     cairo_paginated_surface_t *surface;
     cairo_status_t status;
 
-    surface = malloc (sizeof (cairo_paginated_surface_t));
+    surface = _cairo_malloc (sizeof (cairo_paginated_surface_t));
     if (unlikely (surface == NULL)) {
 	status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
 	goto FAIL;
@@ -107,7 +107,8 @@
     _cairo_surface_init (&surface->base,
 			 &cairo_paginated_surface_backend,
 			 NULL, /* device */
-			 content);
+			 content,
+			 target->is_vector);
 
     /* Override surface->base.type with target's type so we don't leak
      * evidence of the paginated wrapper out to the user. */
@@ -290,6 +291,63 @@
 }
 
 static cairo_int_status_t
+_paint_thumbnail_image (cairo_paginated_surface_t *surface,
+			int                        width,
+			int                        height)
+{
+    cairo_surface_pattern_t pattern;
+    cairo_rectangle_int_t extents;
+    double x_scale;
+    double y_scale;
+    cairo_surface_t *image = NULL;
+    cairo_surface_t *opaque = NULL;
+    cairo_status_t status = CAIRO_STATUS_SUCCESS;
+
+    _cairo_surface_get_extents (surface->target, &extents);
+    x_scale = (double)width / extents.width;
+    y_scale = (double)height / extents.height;
+
+    image = _cairo_paginated_surface_create_image_surface (surface, width, height);
+    cairo_surface_set_device_scale (image, x_scale, y_scale);
+    cairo_surface_set_device_offset (image, -extents.x*x_scale, -extents.y*y_scale);
+    status = _cairo_recording_surface_replay (surface->recording_surface, image);
+    if (unlikely (status))
+	goto cleanup;
+
+    /* flatten transparency */
+
+    opaque = cairo_image_surface_create (CAIRO_FORMAT_RGB24, width, height);
+    if (unlikely (opaque->status)) {
+	status = opaque->status;
+	goto cleanup;
+    }
+
+    status = _cairo_surface_paint (opaque,
+				   CAIRO_OPERATOR_SOURCE,
+				   &_cairo_pattern_white.base,
+				   NULL);
+    if (unlikely (status))
+	goto cleanup;
+
+    _cairo_pattern_init_for_surface (&pattern, image);
+    pattern.base.filter = CAIRO_FILTER_NEAREST;
+    status = _cairo_surface_paint (opaque, CAIRO_OPERATOR_OVER, &pattern.base, NULL);
+    _cairo_pattern_fini (&pattern.base);
+    if (unlikely (status))
+	goto cleanup;
+
+    status = surface->backend->set_thumbnail_image (surface->target, (cairo_image_surface_t *)opaque);
+
+  cleanup:
+    if (image)
+	cairo_surface_destroy (image);
+    if (opaque)
+	cairo_surface_destroy (opaque);
+
+    return status;
+}
+
+static cairo_int_status_t
 _paint_fallback_image (cairo_paginated_surface_t *surface,
 		       cairo_rectangle_int_t     *rect)
 {
@@ -351,10 +409,13 @@
     if (unlikely (analysis->status))
 	return _cairo_surface_set_error (surface->target, analysis->status);
 
-    surface->backend->set_paginated_mode (surface->target,
+    status = surface->backend->set_paginated_mode (surface->target,
 	                                  CAIRO_PAGINATED_MODE_ANALYZE);
+    if (unlikely (status))
+	goto FAIL;
+
     status = _cairo_recording_surface_replay_and_create_regions (surface->recording_surface,
-								 analysis);
+								 NULL, analysis, FALSE);
     if (status)
 	goto FAIL;
 
@@ -400,8 +461,10 @@
     }
 
     if (has_supported) {
-	surface->backend->set_paginated_mode (surface->target,
-		                              CAIRO_PAGINATED_MODE_RENDER);
+	status = surface->backend->set_paginated_mode (surface->target,
+						       CAIRO_PAGINATED_MODE_RENDER);
+	if (unlikely (status))
+	    goto FAIL;
 
 	status = _cairo_recording_surface_replay_region (surface->recording_surface,
 							 NULL,
@@ -416,8 +479,10 @@
 	cairo_rectangle_int_t extents;
 	cairo_bool_t is_bounded;
 
-	surface->backend->set_paginated_mode (surface->target,
-		                              CAIRO_PAGINATED_MODE_FALLBACK);
+	status = surface->backend->set_paginated_mode (surface->target,
+						       CAIRO_PAGINATED_MODE_FALLBACK);
+	if (unlikely (status))
+	    goto FAIL;
 
 	is_bounded = _cairo_surface_get_extents (surface->target, &extents);
 	if (! is_bounded) {
@@ -434,8 +499,10 @@
         cairo_region_t *region;
         int num_rects, i;
 
-	surface->backend->set_paginated_mode (surface->target,
+	status = surface->backend->set_paginated_mode (surface->target,
 		                              CAIRO_PAGINATED_MODE_FALLBACK);
+	if (unlikely (status))
+	    goto FAIL;
 
 	region = _cairo_analysis_surface_get_unsupported (analysis);
 
@@ -450,6 +517,13 @@
 	}
     }
 
+    if (surface->backend->requires_thumbnail_image) {
+	int width, height;
+
+	if (surface->backend->requires_thumbnail_image (surface->target, &width, &height))
+	    _paint_thumbnail_image (surface, width, height);
+    }
+
   FAIL:
     cairo_surface_destroy (analysis);
 
@@ -659,6 +733,26 @@
     return NULL;
 }
 
+static cairo_int_status_t
+_cairo_paginated_surface_tag (void			 *abstract_surface,
+			      cairo_bool_t                begin,
+			      const char                 *tag_name,
+			      const char                 *attributes,
+			      const cairo_pattern_t	 *source,
+			      const cairo_stroke_style_t *style,
+			      const cairo_matrix_t	 *ctm,
+			      const cairo_matrix_t	 *ctm_inverse,
+			      const cairo_clip_t	 *clip)
+{
+    cairo_paginated_surface_t *surface = abstract_surface;
+
+    return _cairo_surface_tag (surface->recording_surface,
+			       begin, tag_name, attributes,
+			       source, style,
+			       ctm, ctm_inverse,
+			       clip);
+}
+
 static cairo_surface_t *
 _cairo_paginated_surface_snapshot (void *abstract_other)
 {
@@ -713,4 +807,5 @@
     _cairo_paginated_surface_has_show_text_glyphs,
     _cairo_paginated_surface_show_text_glyphs,
     _cairo_paginated_surface_get_supported_mime_types,
+    _cairo_paginated_surface_tag,
 };

Modified: trunk/Build/source/libs/cairo/cairo-src/src/cairo-path-bounds.c
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/src/cairo-path-bounds.c	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/src/cairo-path-bounds.c	2018-10-20 03:19:36 UTC (rev 48952)
@@ -154,6 +154,7 @@
 _cairo_path_fixed_approximate_stroke_extents (const cairo_path_fixed_t *path,
 					      const cairo_stroke_style_t *style,
 					      const cairo_matrix_t *ctm,
+					      cairo_bool_t is_vector,
 					      cairo_rectangle_int_t *extents)
 {
     if (path->has_extents) {
@@ -161,7 +162,18 @@
 	double dx, dy;
 
 	_cairo_stroke_style_max_distance_from_path (style, path, ctm, &dx, &dy);
+	if (is_vector)
+	{
+	    /* When calculating extents for vector surfaces, ensure lines thinner
+	     * than the fixed point resolution are not optimized away. */
+	    double min = _cairo_fixed_to_double (CAIRO_FIXED_EPSILON*2);
+	    if (dx < min)
+		dx = min;
 
+	    if (dy < min)
+		dy = min;
+	}
+
 	box_extents = path->extents;
 	box_extents.p1.x -= _cairo_fixed_from_double (dx);
 	box_extents.p1.y -= _cairo_fixed_from_double (dy);
@@ -185,7 +197,18 @@
 {
     cairo_polygon_t polygon;
     cairo_status_t status;
+    cairo_stroke_style_t style;
 
+    /* When calculating extents for vector surfaces, ensure lines thinner
+     * than one point are not optimized away. */
+    double min_line_width = _cairo_matrix_transformed_circle_major_axis (ctm_inverse, 1.0);
+    if (stroke_style->line_width < min_line_width)
+    {
+	style = *stroke_style;
+	style.line_width = min_line_width;
+	stroke_style = &style;
+    }
+
     _cairo_polygon_init (&polygon, NULL, 0);
     status = _cairo_path_fixed_stroke_to_polygon (path,
 						  stroke_style,

Modified: trunk/Build/source/libs/cairo/cairo-src/src/cairo-path-fixed.c
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/src/cairo-path-fixed.c	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/src/cairo-path-fixed.c	2018-10-20 03:19:36 UTC (rev 48952)
@@ -325,7 +325,7 @@
 {
     cairo_path_fixed_t	*path;
 
-    path = malloc (sizeof (cairo_path_fixed_t));
+    path = _cairo_malloc (sizeof (cairo_path_fixed_t));
     if (!path) {
 	_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
 	return NULL;
@@ -347,7 +347,7 @@
 	_cairo_path_buf_destroy (this);
     }
 
-    VG (VALGRIND_MAKE_MEM_NOACCESS (path, sizeof (cairo_path_fixed_t)));
+    VG (VALGRIND_MAKE_MEM_UNDEFINED (path, sizeof (cairo_path_fixed_t)));
 }
 
 void

Modified: trunk/Build/source/libs/cairo/cairo-src/src/cairo-path.c
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/src/cairo-path.c	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/src/cairo-path.c	2018-10-20 03:19:36 UTC (rev 48952)
@@ -294,7 +294,7 @@
     if (status == CAIRO_STATUS_NO_MEMORY)
 	return (cairo_path_t*) &_cairo_path_nil;
 
-    path = malloc (sizeof (cairo_path_t));
+    path = _cairo_malloc (sizeof (cairo_path_t));
     if (unlikely (path == NULL)) {
 	_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
 	return (cairo_path_t*) &_cairo_path_nil;
@@ -314,7 +314,7 @@
 {
     cairo_path_t *path;
 
-    path = malloc (sizeof (cairo_path_t));
+    path = _cairo_malloc (sizeof (cairo_path_t));
     if (unlikely (path == NULL)) {
 	_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
 	return (cairo_path_t*) &_cairo_path_nil;

Modified: trunk/Build/source/libs/cairo/cairo-src/src/cairo-pattern-private.h
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/src/cairo-pattern-private.h	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/src/cairo-pattern-private.h	2018-10-20 03:19:36 UTC (rev 48952)
@@ -256,6 +256,11 @@
 				  const cairo_rectangle_int_t *extents,
 				  cairo_color_t *color);
 
+cairo_private cairo_bool_t
+_cairo_pattern_is_constant_alpha (const cairo_pattern_t          *abstract_pattern,
+				  const cairo_rectangle_int_t    *extents,
+				  double                         *alpha);
+
 cairo_private void
 _cairo_gradient_pattern_fit_to_range (const cairo_gradient_pattern_t *gradient,
 				      double			      max_value,
@@ -296,7 +301,8 @@
 
 cairo_private void
 _cairo_pattern_get_extents (const cairo_pattern_t	    *pattern,
-			    cairo_rectangle_int_t           *extents);
+			    cairo_rectangle_int_t           *extents,
+			    cairo_bool_t                   is_vector);
 
 cairo_private cairo_int_status_t
 _cairo_pattern_get_ink_extents (const cairo_pattern_t	    *pattern,

Modified: trunk/Build/source/libs/cairo/cairo-src/src/cairo-pattern.c
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/src/cairo-pattern.c	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/src/cairo-pattern.c	2018-10-20 03:19:36 UTC (rev 48952)
@@ -357,6 +357,7 @@
     /* The reference count and user_data array are unique to the copy. */
     CAIRO_REFERENCE_COUNT_INIT (&pattern->ref_count, 0);
     _cairo_user_data_array_init (&pattern->user_data);
+    cairo_list_init (&pattern->observers);
 
     return CAIRO_STATUS_SUCCESS;
 }
@@ -396,6 +397,7 @@
 
     CAIRO_REFERENCE_COUNT_INIT (&pattern->ref_count, 0);
     _cairo_user_data_array_init (&pattern->user_data);
+    cairo_list_init (&pattern->observers);
 }
 
 cairo_status_t
@@ -464,19 +466,19 @@
 #if HAVE_VALGRIND
     switch (pattern->type) {
     case CAIRO_PATTERN_TYPE_SOLID:
-	VALGRIND_MAKE_MEM_NOACCESS (pattern, sizeof (cairo_solid_pattern_t));
+	VALGRIND_MAKE_MEM_UNDEFINED (pattern, sizeof (cairo_solid_pattern_t));
 	break;
     case CAIRO_PATTERN_TYPE_SURFACE:
-	VALGRIND_MAKE_MEM_NOACCESS (pattern, sizeof (cairo_surface_pattern_t));
+	VALGRIND_MAKE_MEM_UNDEFINED (pattern, sizeof (cairo_surface_pattern_t));
 	break;
     case CAIRO_PATTERN_TYPE_LINEAR:
-	VALGRIND_MAKE_MEM_NOACCESS (pattern, sizeof (cairo_linear_pattern_t));
+	VALGRIND_MAKE_MEM_UNDEFINED (pattern, sizeof (cairo_linear_pattern_t));
 	break;
     case CAIRO_PATTERN_TYPE_RADIAL:
-	VALGRIND_MAKE_MEM_NOACCESS (pattern, sizeof (cairo_radial_pattern_t));
+	VALGRIND_MAKE_MEM_UNDEFINED (pattern, sizeof (cairo_radial_pattern_t));
 	break;
     case CAIRO_PATTERN_TYPE_MESH:
-	VALGRIND_MAKE_MEM_NOACCESS (pattern, sizeof (cairo_mesh_pattern_t));
+	VALGRIND_MAKE_MEM_UNDEFINED (pattern, sizeof (cairo_mesh_pattern_t));
 	break;
     case CAIRO_PATTERN_TYPE_RASTER_SOURCE:
 	break;
@@ -496,22 +498,22 @@
 
     switch (other->type) {
     case CAIRO_PATTERN_TYPE_SOLID:
-	pattern = malloc (sizeof (cairo_solid_pattern_t));
+	pattern = _cairo_malloc (sizeof (cairo_solid_pattern_t));
 	break;
     case CAIRO_PATTERN_TYPE_SURFACE:
-	pattern = malloc (sizeof (cairo_surface_pattern_t));
+	pattern = _cairo_malloc (sizeof (cairo_surface_pattern_t));
 	break;
     case CAIRO_PATTERN_TYPE_LINEAR:
-	pattern = malloc (sizeof (cairo_linear_pattern_t));
+	pattern = _cairo_malloc (sizeof (cairo_linear_pattern_t));
 	break;
     case CAIRO_PATTERN_TYPE_RADIAL:
-	pattern = malloc (sizeof (cairo_radial_pattern_t));
+	pattern = _cairo_malloc (sizeof (cairo_radial_pattern_t));
 	break;
     case CAIRO_PATTERN_TYPE_MESH:
-	pattern = malloc (sizeof (cairo_mesh_pattern_t));
+	pattern = _cairo_malloc (sizeof (cairo_mesh_pattern_t));
 	break;
     case CAIRO_PATTERN_TYPE_RASTER_SOURCE:
-	pattern = malloc (sizeof (cairo_raster_source_pattern_t));
+	pattern = _cairo_malloc (sizeof (cairo_raster_source_pattern_t));
 	break;
     default:
 	ASSERT_NOT_REACHED;
@@ -602,7 +604,7 @@
 	_freed_pool_get (&freed_pattern_pool[CAIRO_PATTERN_TYPE_SOLID]);
     if (unlikely (pattern == NULL)) {
 	/* None cached, need to create a new pattern. */
-	pattern = malloc (sizeof (cairo_solid_pattern_t));
+	pattern = _cairo_malloc (sizeof (cairo_solid_pattern_t));
 	if (unlikely (pattern == NULL)) {
 	    _cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
 	    return (cairo_pattern_t *) &_cairo_pattern_nil;
@@ -736,7 +738,7 @@
     pattern =
 	_freed_pool_get (&freed_pattern_pool[CAIRO_PATTERN_TYPE_SURFACE]);
     if (unlikely (pattern == NULL)) {
-	pattern = malloc (sizeof (cairo_surface_pattern_t));
+	pattern = _cairo_malloc (sizeof (cairo_surface_pattern_t));
 	if (unlikely (pattern == NULL)) {
 	    _cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
 	    return (cairo_pattern_t *)&_cairo_pattern_nil.base;
@@ -788,7 +790,7 @@
     pattern =
 	_freed_pool_get (&freed_pattern_pool[CAIRO_PATTERN_TYPE_LINEAR]);
     if (unlikely (pattern == NULL)) {
-	pattern = malloc (sizeof (cairo_linear_pattern_t));
+	pattern = _cairo_malloc (sizeof (cairo_linear_pattern_t));
 	if (unlikely (pattern == NULL)) {
 	    _cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
 	    return (cairo_pattern_t *) &_cairo_pattern_nil.base;
@@ -842,7 +844,7 @@
     pattern =
 	_freed_pool_get (&freed_pattern_pool[CAIRO_PATTERN_TYPE_RADIAL]);
     if (unlikely (pattern == NULL)) {
-	pattern = malloc (sizeof (cairo_radial_pattern_t));
+	pattern = _cairo_malloc (sizeof (cairo_radial_pattern_t));
 	if (unlikely (pattern == NULL)) {
 	    _cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
 	    return (cairo_pattern_t *) &_cairo_pattern_nil.base;
@@ -1020,7 +1022,7 @@
     pattern =
 	_freed_pool_get (&freed_pattern_pool[CAIRO_PATTERN_TYPE_MESH]);
     if (unlikely (pattern == NULL)) {
-	pattern = malloc (sizeof (cairo_mesh_pattern_t));
+	pattern = _cairo_malloc (sizeof (cairo_mesh_pattern_t));
 	if (unlikely (pattern == NULL)) {
 	    _cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
 	    return (cairo_pattern_t *) &_cairo_pattern_nil.base;
@@ -1045,8 +1047,8 @@
  * @pattern from being destroyed until a matching call to
  * cairo_pattern_destroy() is made.
  *
- * The number of references to a #cairo_pattern_t can be get using
- * cairo_pattern_get_reference_count().
+ * Use cairo_pattern_get_reference_count() to get the number of
+ * references to a #cairo_pattern_t.
  *
  * Return value: the referenced #cairo_pattern_t.
  *
@@ -1071,8 +1073,8 @@
  * cairo_pattern_get_type:
  * @pattern: a #cairo_pattern_t
  *
- * This function returns the type a pattern.
- * See #cairo_pattern_type_t for available types.
+ * Get the pattern's type.  See #cairo_pattern_type_t for available
+ * types.
  *
  * Return value: The type of @pattern.
  *
@@ -3132,6 +3134,59 @@
     return TRUE;
 }
 
+/**
+ * _cairo_pattern_is_constant_alpha:
+ *
+ * Convenience function to determine whether a pattern has constant
+ * alpha within the given extents. In this case the alpha argument is
+ * initialized to the alpha within the extents.
+ *
+ * Return value: %TRUE if the pattern has constant alpha.
+ **/
+cairo_bool_t
+_cairo_pattern_is_constant_alpha (const cairo_pattern_t         *abstract_pattern,
+				  const cairo_rectangle_int_t   *extents,
+				  double                        *alpha)
+{
+    const cairo_pattern_union_t *pattern;
+    cairo_color_t color;
+
+    if (_cairo_pattern_is_clear (abstract_pattern)) {
+	*alpha = 0.0;
+	return TRUE;
+    }
+
+    if (_cairo_pattern_is_opaque (abstract_pattern, extents)) {
+	*alpha = 1.0;
+	return TRUE;
+    }
+
+    pattern = (cairo_pattern_union_t *) abstract_pattern;
+    switch (pattern->base.type) {
+    case CAIRO_PATTERN_TYPE_SOLID:
+	*alpha = pattern->solid.color.alpha;
+	return TRUE;
+
+    case CAIRO_PATTERN_TYPE_LINEAR:
+    case CAIRO_PATTERN_TYPE_RADIAL:
+	if (_cairo_gradient_pattern_is_solid (&pattern->gradient.base, extents, &color)) {
+	    *alpha = color.alpha;
+	    return TRUE;
+	} else {
+	    return FALSE;
+	}
+
+	/* TODO: need to test these as well */
+    case CAIRO_PATTERN_TYPE_SURFACE:
+    case CAIRO_PATTERN_TYPE_RASTER_SOURCE:
+    case CAIRO_PATTERN_TYPE_MESH:
+	return FALSE;
+    }
+
+    ASSERT_NOT_REACHED;
+    return FALSE;
+}
+
 static cairo_bool_t
 _mesh_is_clear (const cairo_mesh_pattern_t *mesh)
 {
@@ -3522,6 +3577,9 @@
  * For unbounded patterns, the @extents will be initialized with
  * "infinite" extents, (minimum and maximum fixed-point values).
  *
+ * When is_vector is TRUE, avoid rounding to zero widths or heights that
+ * are less than 1 unit.
+ *
  * XXX: Currently, bounded gradient patterns will also return
  * "infinite" extents, though it would be possible to optimize these
  * with a little more work.
@@ -3528,7 +3586,8 @@
  **/
 void
 _cairo_pattern_get_extents (const cairo_pattern_t         *pattern,
-			    cairo_rectangle_int_t         *extents)
+			    cairo_rectangle_int_t         *extents,
+			    cairo_bool_t                   is_vector)
 {
     double x1, y1, x2, y2;
     int ix1, ix2, iy1, iy2;
@@ -3731,6 +3790,8 @@
     else
 	ix2 = _cairo_lround (x2);
     extents->x = ix1; extents->width  = ix2 - ix1;
+    if (is_vector && extents->width == 0 && x1 != x2)
+	extents->width += 1;
 
     if (!round_y) {
 	y1 -= 0.5;
@@ -3745,6 +3806,8 @@
     else
 	iy2 = _cairo_lround (y2);
     extents->y = iy1; extents->height = iy2 - iy1;
+    if (is_vector && extents->height == 0 && y1 != y2)
+	extents->height += 1;
 
     return;
 
@@ -3796,7 +3859,7 @@
 	}
     }
 
-    _cairo_pattern_get_extents (pattern, extents);
+    _cairo_pattern_get_extents (pattern, extents, TRUE);
     return CAIRO_STATUS_SUCCESS;
 }
 
@@ -4417,7 +4480,7 @@
 
     patch = _cairo_array_index_const (&mesh->patches, patch_num);
 
-    path = malloc (sizeof (cairo_path_t));
+    path = _cairo_malloc (sizeof (cairo_path_t));
     if (path == NULL)
 	return _cairo_path_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
 
@@ -4607,7 +4670,36 @@
 _cairo_debug_print_surface_pattern (FILE *file,
 				    const cairo_surface_pattern_t *pattern)
 {
-    printf ("  surface type: %d\n", pattern->surface->type);
+    const char *s;
+    switch (pattern->surface->type) {
+    case CAIRO_SURFACE_TYPE_IMAGE: s = "image"; break;
+    case CAIRO_SURFACE_TYPE_PDF: s = "pdf"; break;
+    case CAIRO_SURFACE_TYPE_PS: s = "ps"; break;
+    case CAIRO_SURFACE_TYPE_XLIB: s = "xlib"; break;
+    case CAIRO_SURFACE_TYPE_XCB: s = "xcb"; break;
+    case CAIRO_SURFACE_TYPE_GLITZ: s = "glitz"; break;
+    case CAIRO_SURFACE_TYPE_QUARTZ: s = "quartz"; break;
+    case CAIRO_SURFACE_TYPE_WIN32: s = "win32"; break;
+    case CAIRO_SURFACE_TYPE_BEOS: s = "beos"; break;
+    case CAIRO_SURFACE_TYPE_DIRECTFB: s = "directfb"; break;
+    case CAIRO_SURFACE_TYPE_SVG: s = "svg"; break;
+    case CAIRO_SURFACE_TYPE_OS2: s = "os2"; break;
+    case CAIRO_SURFACE_TYPE_WIN32_PRINTING: s = "win32_printing"; break;
+    case CAIRO_SURFACE_TYPE_QUARTZ_IMAGE: s = "quartz_image"; break;
+    case CAIRO_SURFACE_TYPE_SCRIPT: s = "script"; break;
+    case CAIRO_SURFACE_TYPE_QT: s = "qt"; break;
+    case CAIRO_SURFACE_TYPE_RECORDING: s = "recording"; break;
+    case CAIRO_SURFACE_TYPE_VG: s = "vg"; break;
+    case CAIRO_SURFACE_TYPE_GL: s = "gl"; break;
+    case CAIRO_SURFACE_TYPE_DRM: s = "drm"; break;
+    case CAIRO_SURFACE_TYPE_TEE: s = "tee"; break;
+    case CAIRO_SURFACE_TYPE_XML: s = "xml"; break;
+    case CAIRO_SURFACE_TYPE_SKIA: s = "skia"; break; /* Deprecated */
+    case CAIRO_SURFACE_TYPE_SUBSURFACE: s = "subsurface"; break;
+    case CAIRO_SURFACE_TYPE_COGL: s = "cogl"; break;
+    default: s = "invalid"; ASSERT_NOT_REACHED; break;
+    }
+    fprintf (file, "  surface type: %s\n", s);
 }
 
 static void

Added: trunk/Build/source/libs/cairo/cairo-src/src/cairo-pdf-interchange.c
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/src/cairo-pdf-interchange.c	                        (rev 0)
+++ trunk/Build/source/libs/cairo/cairo-src/src/cairo-pdf-interchange.c	2018-10-20 03:19:36 UTC (rev 48952)
@@ -0,0 +1,1728 @@
+/* -*- Mode: c; c-basic-offset: 4; indent-tabs-mode: t; tab-width: 8; -*- */
+/* cairo - a vector graphics library with display and print output
+ *
+ * Copyright © 2016 Adrian Johnson
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it either under the terms of the GNU Lesser General Public
+ * License version 2.1 as published by the Free Software Foundation
+ * (the "LGPL") or, at your option, under the terms of the Mozilla
+ * Public License Version 1.1 (the "MPL"). If you do not alter this
+ * notice, a recipient may use your version of this file under either
+ * the MPL or the LGPL.
+ *
+ * You should have received a copy of the LGPL along with this library
+ * in the file COPYING-LGPL-2.1; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
+ * You should have received a copy of the MPL along with this library
+ * in the file COPYING-MPL-1.1
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
+ * OF ANY KIND, either express or implied. See the LGPL or the MPL for
+ * the specific language governing rights and limitations.
+ *
+ * The Original Code is the cairo graphics library.
+ *
+ * The Initial Developer of the Original Code is Adrian Johnson.
+ *
+ * Contributor(s):
+ *	Adrian Johnson <ajohnson at redneon.com>
+ */
+
+
+/* PDF Document Interchange features:
+ *  - metadata
+ *  - document outline
+ *  - tagged pdf
+ *  - hyperlinks
+ *  - page labels
+ */
+
+#define _DEFAULT_SOURCE /* for localtime_r(), gmtime_r(), snprintf(), strdup() */
+#include "cairoint.h"
+
+#include "cairo-pdf.h"
+#include "cairo-pdf-surface-private.h"
+
+#include "cairo-array-private.h"
+#include "cairo-error-private.h"
+#include "cairo-output-stream-private.h"
+
+#include <time.h>
+
+#ifndef HAVE_LOCALTIME_R
+#define localtime_r(T, BUF) (*(BUF) = *localtime (T))
+#endif
+#ifndef HAVE_GMTIME_R
+#define gmtime_r(T, BUF) (*(BUF) = *gmtime (T))
+#endif
+
+static void
+write_rect_to_pdf_quad_points (cairo_output_stream_t   *stream,
+			       const cairo_rectangle_t *rect,
+			       double                   surface_height)
+{
+    _cairo_output_stream_printf (stream,
+				 "%f %f %f %f %f %f %f %f",
+				 rect->x,
+				 surface_height - rect->y,
+				 rect->x + rect->width,
+				 surface_height - rect->y,
+				 rect->x + rect->width,
+				 surface_height - (rect->y + rect->height),
+				 rect->x,
+				 surface_height - (rect->y + rect->height));
+}
+
+static void
+write_rect_int_to_pdf_bbox (cairo_output_stream_t       *stream,
+			    const cairo_rectangle_int_t *rect,
+			    double                       surface_height)
+{
+    _cairo_output_stream_printf (stream,
+				 "%d %f %d %f",
+				 rect->x,
+				 surface_height - (rect->y + rect->height),
+				 rect->x + rect->width,
+				 surface_height - rect->y);
+}
+
+static cairo_int_status_t
+add_tree_node (cairo_pdf_surface_t           *surface,
+	       cairo_pdf_struct_tree_node_t  *parent,
+	       const char                    *name,
+	       cairo_pdf_struct_tree_node_t **new_node)
+{
+    cairo_pdf_struct_tree_node_t *node;
+
+    node = _cairo_malloc (sizeof(cairo_pdf_struct_tree_node_t));
+    if (unlikely (node == NULL))
+	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
+
+    node->name = strdup (name);
+    node->res = _cairo_pdf_surface_new_object (surface);
+    if (node->res.id == 0)
+	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
+
+    node->parent = parent;
+    cairo_list_init (&node->children);
+    _cairo_array_init (&node->mcid, sizeof(struct page_mcid));
+    node->annot_res.id = 0;
+    node->extents.valid = FALSE;
+    cairo_list_init (&node->extents.link);
+
+    cairo_list_add_tail (&node->link, &parent->children);
+
+    *new_node = node;
+    return CAIRO_STATUS_SUCCESS;
+}
+
+static cairo_bool_t
+is_leaf_node (cairo_pdf_struct_tree_node_t *node)
+{
+    return node->parent && cairo_list_is_empty (&node->children) ;
+}
+
+static void
+free_node (cairo_pdf_struct_tree_node_t *node)
+{
+    cairo_pdf_struct_tree_node_t *child, *next;
+
+    if (!node)
+	return;
+
+    cairo_list_foreach_entry_safe (child, next, cairo_pdf_struct_tree_node_t,
+				   &node->children, link)
+    {
+	cairo_list_del (&child->link);
+	free_node (child);
+    }
+    free (node->name);
+    _cairo_array_fini (&node->mcid);
+    free (node);
+}
+
+static cairo_status_t
+add_mcid_to_node (cairo_pdf_surface_t          *surface,
+		  cairo_pdf_struct_tree_node_t *node,
+		  int                           page,
+		  int                          *mcid)
+{
+    struct page_mcid mcid_elem;
+    cairo_int_status_t status;
+    cairo_pdf_interchange_t *ic = &surface->interchange;
+
+    status = _cairo_array_append (&ic->mcid_to_tree, &node);
+    if (unlikely (status))
+	return status;
+
+    mcid_elem.page = page;
+    mcid_elem.mcid = _cairo_array_num_elements (&ic->mcid_to_tree) - 1;
+    *mcid = mcid_elem.mcid;
+    return _cairo_array_append (&node->mcid, &mcid_elem);
+}
+
+static cairo_int_status_t
+add_annotation (cairo_pdf_surface_t           *surface,
+		cairo_pdf_struct_tree_node_t  *node,
+		const char                    *name,
+		const char                    *attributes)
+{
+    cairo_int_status_t status = CAIRO_STATUS_SUCCESS;
+    cairo_pdf_interchange_t *ic = &surface->interchange;
+    cairo_pdf_annotation_t *annot;
+
+    annot = malloc (sizeof(cairo_pdf_annotation_t));
+    if (unlikely (annot == NULL))
+	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
+
+    status = _cairo_tag_parse_link_attributes (attributes, &annot->link_attrs);
+    if (unlikely (status)) {
+	free (annot);
+	return status;
+    }
+
+    annot->node = node;
+
+    status = _cairo_array_append (&ic->annots, &annot);
+
+    return status;
+}
+
+static void
+free_annotation (cairo_pdf_annotation_t *annot)
+{
+    _cairo_array_fini (&annot->link_attrs.rects);
+    free (annot->link_attrs.dest);
+    free (annot->link_attrs.uri);
+    free (annot->link_attrs.file);
+    free (annot);
+}
+
+static void
+cairo_pdf_interchange_clear_annotations (cairo_pdf_surface_t *surface)
+{
+    cairo_pdf_interchange_t *ic = &surface->interchange;
+    int num_elems, i;
+
+    num_elems = _cairo_array_num_elements (&ic->annots);
+    for (i = 0; i < num_elems; i++) {
+	cairo_pdf_annotation_t * annot;
+
+	_cairo_array_copy_element (&ic->annots, i, &annot);
+	free_annotation (annot);
+    }
+    _cairo_array_truncate (&ic->annots, 0);
+}
+
+static cairo_int_status_t
+cairo_pdf_interchange_write_node_object (cairo_pdf_surface_t            *surface,
+					 cairo_pdf_struct_tree_node_t   *node)
+{
+    struct page_mcid *mcid_elem;
+    int i, num_mcid, first_page;
+    cairo_pdf_resource_t *page_res;
+    cairo_pdf_struct_tree_node_t *child;
+
+    _cairo_pdf_surface_update_object (surface, node->res);
+    _cairo_output_stream_printf (surface->output,
+				 "%d 0 obj\n"
+				 "<< /Type /StructElem\n"
+				 "   /S /%s\n"
+				 "   /P %d 0 R\n",
+				 node->res.id,
+				 node->name,
+				 node->parent->res.id);
+
+    if (! cairo_list_is_empty (&node->children)) {
+	if (cairo_list_is_singular (&node->children) && node->annot_res.id == 0) {
+	    child = cairo_list_first_entry (&node->children, cairo_pdf_struct_tree_node_t, link);
+	    _cairo_output_stream_printf (surface->output, "   /K %d 0 R\n", child->res.id);
+	} else {
+	    _cairo_output_stream_printf (surface->output, "   /K [ ");
+	    if (node->annot_res.id != 0) {
+		_cairo_output_stream_printf (surface->output,
+					     "<< /Type /OBJR /Obj %d 0 R >> ",
+					     node->annot_res.id);
+	    }
+	    cairo_list_foreach_entry (child, cairo_pdf_struct_tree_node_t,
+				      &node->children, link)
+	    {
+		_cairo_output_stream_printf (surface->output, "%d 0 R ", child->res.id);
+	    }
+	    _cairo_output_stream_printf (surface->output, "]\n");
+	}
+    } else {
+	num_mcid = _cairo_array_num_elements (&node->mcid);
+	if (num_mcid > 0 ) {
+	    mcid_elem = _cairo_array_index (&node->mcid, 0);
+	    first_page = mcid_elem->page;
+	    page_res = _cairo_array_index (&surface->pages, first_page - 1);
+	    _cairo_output_stream_printf (surface->output, "   /Pg %d 0 R\n", page_res->id);
+
+	    if (num_mcid == 1 && node->annot_res.id == 0) {
+		_cairo_output_stream_printf (surface->output, "   /K %d\n", mcid_elem->mcid);
+	    } else {
+		_cairo_output_stream_printf (surface->output, "   /K [ ");
+		if (node->annot_res.id != 0) {
+		    _cairo_output_stream_printf (surface->output,
+						 "<< /Type /OBJR /Obj %d 0 R >> ",
+						 node->annot_res.id);
+		}
+		for (i = 0; i < num_mcid; i++) {
+		    mcid_elem = _cairo_array_index (&node->mcid, i);
+		    page_res = _cairo_array_index (&surface->pages, mcid_elem->page - 1);
+		    if (mcid_elem->page == first_page) {
+			_cairo_output_stream_printf (surface->output, "%d ", mcid_elem->mcid);
+		    } else {
+			_cairo_output_stream_printf (surface->output,
+						     "\n       << /Type /MCR /Pg %d 0 R /MCID %d >> ",
+						     page_res->id,
+						     mcid_elem->mcid);
+		    }
+		}
+		_cairo_output_stream_printf (surface->output, "]\n");
+	    }
+	}
+    }
+    _cairo_output_stream_printf (surface->output,
+				 ">>\n"
+				 "endobj\n");
+
+    return _cairo_output_stream_get_status (surface->output);
+}
+
+static void
+init_named_dest_key (cairo_pdf_named_dest_t *dest)
+{
+    dest->base.hash = _cairo_hash_bytes (_CAIRO_HASH_INIT_VALUE,
+					 dest->attrs.name,
+					 strlen (dest->attrs.name));
+}
+
+static cairo_bool_t
+_named_dest_equal (const void *key_a, const void *key_b)
+{
+    const cairo_pdf_named_dest_t *a = key_a;
+    const cairo_pdf_named_dest_t *b = key_b;
+
+    return strcmp (a->attrs.name, b->attrs.name) == 0;
+}
+
+static void
+_named_dest_pluck (void *entry, void *closure)
+{
+    cairo_pdf_named_dest_t *dest = entry;
+    cairo_hash_table_t *table = closure;
+
+    _cairo_hash_table_remove (table, &dest->base);
+    free (dest->attrs.name);
+    free (dest);
+}
+
+static cairo_int_status_t
+cairo_pdf_interchange_write_explicit_dest (cairo_pdf_surface_t *surface,
+                                          int                  page,
+                                          cairo_bool_t         has_pos,
+                                          double               x,
+                                          double               y)
+{
+    cairo_pdf_resource_t res;
+    double height;
+
+    if (page < 1 || page > (int)_cairo_array_num_elements (&surface->pages))
+       return CAIRO_INT_STATUS_TAG_ERROR;
+
+    _cairo_array_copy_element (&surface->page_heights, page - 1, &height);
+    _cairo_array_copy_element (&surface->pages, page - 1, &res);
+    if (has_pos) {
+       _cairo_output_stream_printf (surface->output,
+                                    "   /Dest [%d 0 R /XYZ %f %f 0]\n",
+                                    res.id,
+                                    x,
+                                    height - y);
+    } else {
+       _cairo_output_stream_printf (surface->output,
+                                    "   /Dest [%d 0 R /XYZ null null 0]\n",
+                                    res.id);
+    }
+
+    return CAIRO_STATUS_SUCCESS;
+}
+
+static cairo_int_status_t
+cairo_pdf_interchange_write_dest (cairo_pdf_surface_t *surface,
+				  cairo_link_attrs_t  *link_attrs)
+{
+    cairo_int_status_t status;
+    cairo_pdf_interchange_t *ic = &surface->interchange;
+    char *dest = NULL;
+
+    if (link_attrs->dest) {
+	cairo_pdf_named_dest_t key;
+	cairo_pdf_named_dest_t *named_dest;
+
+	/* check if this is a link to an internal named dest */
+	key.attrs.name = link_attrs->dest;
+	init_named_dest_key (&key);
+	named_dest = _cairo_hash_table_lookup (ic->named_dests, &key.base);
+	if (named_dest && named_dest->attrs.internal) {
+	    /* if dests exists and has internal attribute, use a direct
+	     * reference instead of the name */
+	    double x = 0;
+	    double y = 0;
+
+	    if (named_dest->extents.valid) {
+		x = named_dest->extents.extents.x;
+		y = named_dest->extents.extents.y;
+	    }
+
+	    if (named_dest->attrs.x_valid)
+		x = named_dest->attrs.x;
+
+	    if (named_dest->attrs.y_valid)
+		y = named_dest->attrs.y;
+
+	    status = cairo_pdf_interchange_write_explicit_dest (surface,
+								named_dest->page,
+								TRUE,
+								x, y);
+	    return status;
+	}
+    }
+
+    if (link_attrs->dest) {
+	status = _cairo_utf8_to_pdf_string (link_attrs->dest, &dest);
+	if (unlikely (status))
+	    return status;
+
+	_cairo_output_stream_printf (surface->output,
+				     "   /Dest %s\n",
+				     dest);
+	free (dest);
+    } else {
+	status = cairo_pdf_interchange_write_explicit_dest (surface,
+							    link_attrs->page,
+							    link_attrs->has_pos,
+							    link_attrs->pos.x,
+							    link_attrs->pos.y);
+    }
+
+    return CAIRO_STATUS_SUCCESS;
+}
+
+static cairo_int_status_t
+cairo_pdf_interchange_write_link_action (cairo_pdf_surface_t   *surface,
+					 cairo_link_attrs_t    *link_attrs)
+{
+    cairo_int_status_t status;
+    char *dest = NULL;
+
+    if (link_attrs->link_type == TAG_LINK_DEST) {
+	status = cairo_pdf_interchange_write_dest (surface, link_attrs);
+	if (unlikely (status))
+	    return status;
+
+    } else if (link_attrs->link_type == TAG_LINK_URI) {
+	_cairo_output_stream_printf (surface->output,
+				     "   /A <<\n"
+				     "      /Type /Action\n"
+				     "      /S /URI\n"
+				     "      /URI (%s)\n"
+				     "   >>\n",
+				     link_attrs->uri);
+    } else if (link_attrs->link_type == TAG_LINK_FILE) {
+	_cairo_output_stream_printf (surface->output,
+				     "   /A <<\n"
+				     "      /Type /Action\n"
+				     "      /S /GoToR\n"
+				     "      /F (%s)\n",
+				     link_attrs->file);
+	if (link_attrs->dest) {
+	    status = _cairo_utf8_to_pdf_string (link_attrs->dest, &dest);
+	    if (unlikely (status))
+		return status;
+
+	    _cairo_output_stream_printf (surface->output,
+					 "      /D %s\n",
+					 dest);
+	    free (dest);
+	} else {
+	    if (link_attrs->has_pos) {
+		_cairo_output_stream_printf (surface->output,
+					     "      /D [%d %f %f 0]\n",
+					     link_attrs->page,
+					     link_attrs->pos.x,
+					     link_attrs->pos.y);
+	    } else {
+		_cairo_output_stream_printf (surface->output,
+					     "      /D [%d null null 0]\n",
+					     link_attrs->page);
+	    }
+	}
+	_cairo_output_stream_printf (surface->output,
+				     "   >>\n");
+    }
+
+    return CAIRO_STATUS_SUCCESS;
+}
+
+static cairo_int_status_t
+cairo_pdf_interchange_write_annot (cairo_pdf_surface_t    *surface,
+				   cairo_pdf_annotation_t *annot)
+{
+    cairo_int_status_t status = CAIRO_STATUS_SUCCESS;
+    cairo_pdf_interchange_t *ic = &surface->interchange;
+    cairo_pdf_struct_tree_node_t *node = annot->node;
+    int sp;
+    int i, num_rects;
+    double height;
+
+    num_rects = _cairo_array_num_elements (&annot->link_attrs.rects);
+    if (strcmp (node->name, CAIRO_TAG_LINK) == 0 &&
+	annot->link_attrs.link_type != TAG_LINK_EMPTY &&
+	(node->extents.valid || num_rects > 0))
+    {
+	status = _cairo_array_append (&ic->parent_tree, &node->res);
+	if (unlikely (status))
+	    return status;
+
+	sp = _cairo_array_num_elements (&ic->parent_tree) - 1;
+
+	node->annot_res = _cairo_pdf_surface_new_object (surface);
+
+	status = _cairo_array_append (&surface->page_annots, &node->annot_res);
+	if (unlikely (status))
+	    return status;
+
+	_cairo_pdf_surface_update_object (surface, node->annot_res);
+	_cairo_output_stream_printf (surface->output,
+				     "%d 0 obj\n"
+				     "<< /Type /Annot\n"
+				     "   /Subtype /Link\n"
+				     "   /StructParent %d\n",
+				     node->annot_res.id,
+				     sp);
+
+	height = surface->height;
+	if (num_rects > 0) {
+	    cairo_rectangle_int_t bbox_rect;
+
+	    _cairo_output_stream_printf (surface->output,
+					 "   /QuadPoints [ ");
+	    for (i = 0; i < num_rects; i++) {
+		cairo_rectangle_t rectf;
+		cairo_rectangle_int_t recti;
+
+		_cairo_array_copy_element (&annot->link_attrs.rects, i, &rectf);
+		_cairo_rectangle_int_from_double (&recti, &rectf);
+		if (i == 0)
+		    bbox_rect = recti;
+		else
+		    _cairo_rectangle_union (&bbox_rect, &recti);
+
+		write_rect_to_pdf_quad_points (surface->output, &rectf, height);
+		_cairo_output_stream_printf (surface->output, " ");
+	    }
+	    _cairo_output_stream_printf (surface->output,
+					 "]\n"
+					 "   /Rect [ ");
+	    write_rect_int_to_pdf_bbox (surface->output, &bbox_rect, height);
+	    _cairo_output_stream_printf (surface->output, " ]\n");
+	} else {
+	    _cairo_output_stream_printf (surface->output,
+					 "   /Rect [ ");
+	    write_rect_int_to_pdf_bbox (surface->output, &node->extents.extents, height);
+	    _cairo_output_stream_printf (surface->output, " ]\n");
+	}
+
+	status = cairo_pdf_interchange_write_link_action (surface, &annot->link_attrs);
+	if (unlikely (status))
+	    return status;
+
+	_cairo_output_stream_printf (surface->output,
+				     "   /BS << /W 0 >>"
+				     ">>\n"
+				     "endobj\n");
+
+	status = _cairo_output_stream_get_status (surface->output);
+    }
+
+    return status;
+}
+
+static cairo_int_status_t
+cairo_pdf_interchange_walk_struct_tree (cairo_pdf_surface_t          *surface,
+					cairo_pdf_struct_tree_node_t *node,
+					cairo_int_status_t (*func) (cairo_pdf_surface_t *surface,
+								    cairo_pdf_struct_tree_node_t *node))
+{
+    cairo_int_status_t status;
+    cairo_pdf_struct_tree_node_t *child;
+
+    if (node->parent) {
+	status = func (surface, node);
+	if (unlikely (status))
+	    return status;
+    }
+
+    cairo_list_foreach_entry (child, cairo_pdf_struct_tree_node_t,
+			      &node->children, link)
+    {
+	status = cairo_pdf_interchange_walk_struct_tree (surface, child, func);
+	if (unlikely (status))
+	    return status;
+    }
+
+    return CAIRO_STATUS_SUCCESS;
+}
+
+static cairo_int_status_t
+cairo_pdf_interchange_write_struct_tree (cairo_pdf_surface_t *surface)
+{
+    cairo_pdf_interchange_t *ic = &surface->interchange;
+    cairo_pdf_struct_tree_node_t *child;
+
+    if (cairo_list_is_empty (&ic->struct_root->children))
+	return CAIRO_STATUS_SUCCESS;
+
+    surface->struct_tree_root = _cairo_pdf_surface_new_object (surface);
+    ic->struct_root->res = surface->struct_tree_root;
+
+    cairo_pdf_interchange_walk_struct_tree (surface, ic->struct_root, cairo_pdf_interchange_write_node_object);
+
+    child = cairo_list_first_entry (&ic->struct_root->children, cairo_pdf_struct_tree_node_t, link);
+    _cairo_pdf_surface_update_object (surface, surface->struct_tree_root);
+    _cairo_output_stream_printf (surface->output,
+				 "%d 0 obj\n"
+				 "<< /Type /StructTreeRoot\n"
+				 "   /ParentTree %d 0 R\n",
+				 surface->struct_tree_root.id,
+				 ic->parent_tree_res.id);
+
+    if (cairo_list_is_singular (&ic->struct_root->children)) {
+	child = cairo_list_first_entry (&ic->struct_root->children, cairo_pdf_struct_tree_node_t, link);
+	_cairo_output_stream_printf (surface->output, "   /K [ %d 0 R ]\n", child->res.id);
+    } else {
+	_cairo_output_stream_printf (surface->output, "   /K [ ");
+
+	cairo_list_foreach_entry (child, cairo_pdf_struct_tree_node_t,
+				  &ic->struct_root->children, link)
+	{
+	    _cairo_output_stream_printf (surface->output, "%d 0 R ", child->res.id);
+	}
+	_cairo_output_stream_printf (surface->output, "]\n");
+    }
+
+    _cairo_output_stream_printf (surface->output,
+				 ">>\n"
+				 "endobj\n");
+
+    return CAIRO_STATUS_SUCCESS;
+}
+
+static cairo_int_status_t
+cairo_pdf_interchange_write_page_annots (cairo_pdf_surface_t *surface)
+{
+    cairo_pdf_interchange_t *ic = &surface->interchange;
+    int num_elems, i;
+    cairo_int_status_t status = CAIRO_STATUS_SUCCESS;
+
+    num_elems = _cairo_array_num_elements (&ic->annots);
+    for (i = 0; i < num_elems; i++) {
+	cairo_pdf_annotation_t * annot;
+
+	_cairo_array_copy_element (&ic->annots, i, &annot);
+	status = cairo_pdf_interchange_write_annot (surface, annot);
+	if (unlikely (status))
+	    return status;
+    }
+
+    return status;
+}
+
+static cairo_int_status_t
+cairo_pdf_interchange_write_page_parent_elems (cairo_pdf_surface_t *surface)
+{
+    int num_elems, i;
+    cairo_pdf_struct_tree_node_t *node;
+    cairo_pdf_resource_t res;
+    cairo_pdf_interchange_t *ic = &surface->interchange;
+    cairo_int_status_t status = CAIRO_STATUS_SUCCESS;
+
+    surface->page_parent_tree = -1;
+    num_elems = _cairo_array_num_elements (&ic->mcid_to_tree);
+    if (num_elems > 0) {
+	res = _cairo_pdf_surface_new_object (surface);
+	_cairo_output_stream_printf (surface->output,
+				     "%d 0 obj\n"
+				     "[\n",
+				     res.id);
+	for (i = 0; i < num_elems; i++) {
+	    _cairo_array_copy_element (&ic->mcid_to_tree, i, &node);
+	    _cairo_output_stream_printf (surface->output, "  %d 0 R\n", node->res.id);
+	}
+	_cairo_output_stream_printf (surface->output,
+				     "]\n"
+				     "endobj\n");
+	status = _cairo_array_append (&ic->parent_tree, &res);
+	surface->page_parent_tree = _cairo_array_num_elements (&ic->parent_tree) - 1;
+    }
+
+    return status;
+}
+
+static cairo_int_status_t
+cairo_pdf_interchange_write_parent_tree (cairo_pdf_surface_t *surface)
+{
+    int num_elems, i;
+    cairo_pdf_resource_t *res;
+    cairo_pdf_interchange_t *ic = &surface->interchange;
+
+    num_elems = _cairo_array_num_elements (&ic->parent_tree);
+    if (num_elems > 0) {
+	ic->parent_tree_res = _cairo_pdf_surface_new_object (surface);
+	_cairo_output_stream_printf (surface->output,
+				     "%d 0 obj\n"
+				     "<< /Nums [\n",
+				     ic->parent_tree_res.id);
+	for (i = 0; i < num_elems; i++) {
+	    res = _cairo_array_index (&ic->parent_tree, i);
+	    if (res->id) {
+		_cairo_output_stream_printf (surface->output,
+					     "   %d %d 0 R\n",
+					     i,
+					     res->id);
+	    }
+	}
+	_cairo_output_stream_printf (surface->output,
+				     "  ]\n"
+				     ">>\n"
+				     "endobj\n");
+    }
+
+    return CAIRO_STATUS_SUCCESS;
+}
+
+static cairo_int_status_t
+cairo_pdf_interchange_write_outline (cairo_pdf_surface_t *surface)
+{
+    int num_elems, i;
+    cairo_pdf_outline_entry_t *outline;
+    cairo_pdf_interchange_t *ic = &surface->interchange;
+    cairo_int_status_t status;
+    char *name = NULL;
+
+    num_elems = _cairo_array_num_elements (&ic->outline);
+    if (num_elems < 2)
+	return CAIRO_INT_STATUS_SUCCESS;
+
+    _cairo_array_copy_element (&ic->outline, 0, &outline);
+    outline->res = _cairo_pdf_surface_new_object (surface);
+    surface->outlines_dict_res = outline->res;
+    _cairo_output_stream_printf (surface->output,
+				 "%d 0 obj\n"
+				 "<< /Type /Outlines\n"
+				 "   /First %d 0 R\n"
+				 "   /Last %d 0 R\n"
+				 "   /Count %d\n"
+				 ">>\n"
+				 "endobj\n",
+				 outline->res.id,
+				 outline->first_child->res.id,
+				 outline->last_child->res.id,
+				 outline->count);
+
+    for (i = 1; i < num_elems; i++) {
+	_cairo_array_copy_element (&ic->outline, i, &outline);
+	_cairo_pdf_surface_update_object (surface, outline->res);
+
+	status = _cairo_utf8_to_pdf_string (outline->name, &name);
+	if (unlikely (status))
+	    return status;
+
+	_cairo_output_stream_printf (surface->output,
+				     "%d 0 obj\n"
+				     "<< /Title %s\n"
+				     "   /Parent %d 0 R\n",
+				     outline->res.id,
+				     name,
+				     outline->parent->res.id);
+	free (name);
+
+	if (outline->prev) {
+	    _cairo_output_stream_printf (surface->output,
+					 "   /Prev %d 0 R\n",
+					 outline->prev->res.id);
+	}
+
+	if (outline->next) {
+	    _cairo_output_stream_printf (surface->output,
+					 "   /Next %d 0 R\n",
+					 outline->next->res.id);
+	}
+
+	if (outline->first_child) {
+	    _cairo_output_stream_printf (surface->output,
+					 "   /First %d 0 R\n"
+					 "   /Last %d 0 R\n"
+					 "   /Count %d\n",
+					 outline->first_child->res.id,
+					 outline->last_child->res.id,
+					 outline->count);
+	}
+
+	if (outline->flags) {
+	    int flags = 0;
+	    if (outline->flags & CAIRO_PDF_OUTLINE_FLAG_ITALIC)
+		flags |= 1;
+	    if (outline->flags & CAIRO_PDF_OUTLINE_FLAG_BOLD)
+		flags |= 2;
+	    _cairo_output_stream_printf (surface->output,
+					 "   /F %d\n",
+					 flags);
+	}
+
+	status = cairo_pdf_interchange_write_link_action (surface, &outline->link_attrs);
+	if (unlikely (status))
+	    return status;
+
+	_cairo_output_stream_printf (surface->output,
+				     ">>\n"
+				     "endobj\n");
+    }
+
+    return status;
+}
+
+/*
+ * Split a page label into a text prefix and numeric suffix. Leading '0's are
+ * included in the prefix. eg
+ *  "3"     => NULL,    3
+ *  "cover" => "cover", 0
+ *  "A-2"   => "A-",    2
+ *  "A-002" => "A-00",  2
+ */
+static char *
+split_label (const char* label, int *num)
+{
+    int len, i;
+
+    *num = 0;
+    len = strlen (label);
+    if (len == 0)
+	return NULL;
+
+    i = len;
+    while (i > 0 && _cairo_isdigit (label[i-1]))
+	   i--;
+
+    while (i < len && label[i] == '0')
+	i++;
+
+    if (i < len)
+	sscanf (label + i, "%d", num);
+
+    if (i > 0) {
+	char *s;
+	s = _cairo_malloc (i + 1);
+	if (!s)
+	    return NULL;
+
+	memcpy (s, label, i);
+	s[i] = 0;
+	return s;
+    }
+
+    return NULL;
+}
+
+/* strcmp that handles NULL arguments */
+static cairo_bool_t
+strcmp_null (const char *s1, const char *s2)
+{
+    if (s1 && s2)
+	return strcmp (s1, s2) == 0;
+
+    if (!s1 && !s2)
+	return TRUE;
+
+    return FALSE;
+}
+
+static cairo_int_status_t
+cairo_pdf_interchange_write_page_labels (cairo_pdf_surface_t *surface)
+{
+    int num_elems, i;
+    char *label;
+    char *prefix;
+    char *prev_prefix;
+    int num, prev_num;
+    cairo_int_status_t status;
+    cairo_bool_t has_labels;
+
+    /* Check if any labels defined */
+    num_elems = _cairo_array_num_elements (&surface->page_labels);
+    has_labels = FALSE;
+    for (i = 0; i < num_elems; i++) {
+	_cairo_array_copy_element (&surface->page_labels, i, &label);
+	if (label) {
+	    has_labels = TRUE;
+	    break;
+	}
+    }
+
+    if (!has_labels)
+	return CAIRO_STATUS_SUCCESS;
+
+    surface->page_labels_res = _cairo_pdf_surface_new_object (surface);
+    _cairo_output_stream_printf (surface->output,
+				 "%d 0 obj\n"
+				 "<< /Nums [\n",
+				 surface->page_labels_res.id);
+    prefix = NULL;
+    prev_prefix = NULL;
+    num = 0;
+    prev_num = 0;
+    for (i = 0; i < num_elems; i++) {
+	_cairo_array_copy_element (&surface->page_labels, i, &label);
+	if (label) {
+	    prefix = split_label (label, &num);
+	} else {
+	    prefix = NULL;
+	    num = i + 1;
+	}
+
+	if (!strcmp_null (prefix, prev_prefix) || num != prev_num + 1) {
+	    _cairo_output_stream_printf (surface->output,  "   %d << ", i);
+
+	    if (num)
+		_cairo_output_stream_printf (surface->output,  "/S /D /St %d ", num);
+
+	    if (prefix) {
+		char *s;
+		status = _cairo_utf8_to_pdf_string (prefix, &s);
+		if (unlikely (status))
+		    return status;
+
+		_cairo_output_stream_printf (surface->output,  "/P %s ", s);
+		free (s);
+	    }
+
+	    _cairo_output_stream_printf (surface->output,  ">>\n");
+	}
+	free (prev_prefix);
+	prev_prefix = prefix;
+	prefix = NULL;
+	prev_num = num;
+    }
+    free (prefix);
+    free (prev_prefix);
+    _cairo_output_stream_printf (surface->output,
+				 "  ]\n"
+				 ">>\n"
+				 "endobj\n");
+
+    return CAIRO_STATUS_SUCCESS;
+}
+
+static void
+_collect_dest (void *entry, void *closure)
+{
+    cairo_pdf_named_dest_t *dest = entry;
+    cairo_pdf_surface_t *surface = closure;
+    cairo_pdf_interchange_t *ic = &surface->interchange;
+
+    ic->sorted_dests[ic->num_dests++] = dest;
+}
+
+static int
+_dest_compare (const void *a, const void *b)
+{
+    const cairo_pdf_named_dest_t * const *dest_a = a;
+    const cairo_pdf_named_dest_t * const *dest_b = b;
+
+    return strcmp ((*dest_a)->attrs.name, (*dest_b)->attrs.name);
+}
+
+static cairo_int_status_t
+_cairo_pdf_interchange_write_document_dests (cairo_pdf_surface_t *surface)
+{
+    int i;
+    cairo_pdf_interchange_t *ic = &surface->interchange;
+
+    if (ic->num_dests == 0) {
+	ic->dests_res.id = 0;
+        return CAIRO_STATUS_SUCCESS;
+    }
+
+    ic->sorted_dests = calloc (ic->num_dests, sizeof (cairo_pdf_named_dest_t *));
+    if (unlikely (ic->sorted_dests == NULL))
+	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
+
+    ic->num_dests = 0;
+    _cairo_hash_table_foreach (ic->named_dests, _collect_dest, surface);
+    qsort (ic->sorted_dests, ic->num_dests, sizeof (cairo_pdf_named_dest_t *), _dest_compare);
+
+    ic->dests_res = _cairo_pdf_surface_new_object (surface);
+    _cairo_output_stream_printf (surface->output,
+				 "%d 0 obj\n"
+				 "<< /Names [\n",
+				 ic->dests_res.id);
+    for (i = 0; i < ic->num_dests; i++) {
+	cairo_pdf_named_dest_t *dest = ic->sorted_dests[i];
+	cairo_pdf_resource_t page_res;
+	double x = 0;
+	double y = 0;
+	double height;
+
+	if (dest->attrs.internal)
+	    continue;
+
+	if (dest->extents.valid) {
+	    x = dest->extents.extents.x;
+	    y = dest->extents.extents.y;
+	}
+
+	if (dest->attrs.x_valid)
+	    x = dest->attrs.x;
+
+	if (dest->attrs.y_valid)
+	    y = dest->attrs.y;
+
+	_cairo_array_copy_element (&surface->pages, dest->page - 1, &page_res);
+	_cairo_array_copy_element (&surface->page_heights, dest->page - 1, &height);
+	_cairo_output_stream_printf (surface->output,
+				     "   (%s) [%d 0 R /XYZ %f %f 0]\n",
+				     dest->attrs.name,
+				     page_res.id,
+				     x,
+				     height - y);
+    }
+    _cairo_output_stream_printf (surface->output,
+				     "  ]\n"
+				     ">>\n"
+				     "endobj\n");
+
+    return CAIRO_STATUS_SUCCESS;
+}
+
+static cairo_int_status_t
+cairo_pdf_interchange_write_names_dict (cairo_pdf_surface_t *surface)
+{
+    cairo_pdf_interchange_t *ic = &surface->interchange;
+    cairo_int_status_t status;
+
+    status = _cairo_pdf_interchange_write_document_dests (surface);
+    if (unlikely (status))
+	return status;
+
+    surface->names_dict_res.id = 0;
+    if (ic->dests_res.id != 0) {
+	surface->names_dict_res = _cairo_pdf_surface_new_object (surface);
+	_cairo_output_stream_printf (surface->output,
+				     "%d 0 obj\n"
+				     "<< /Dests %d 0 R >>\n"
+				     "endobj\n",
+				     surface->names_dict_res.id,
+				     ic->dests_res.id);
+    }
+
+    return CAIRO_STATUS_SUCCESS;
+}
+
+static cairo_int_status_t
+cairo_pdf_interchange_write_docinfo (cairo_pdf_surface_t *surface)
+{
+    cairo_pdf_interchange_t *ic = &surface->interchange;
+
+    surface->docinfo_res = _cairo_pdf_surface_new_object (surface);
+    if (surface->docinfo_res.id == 0)
+	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
+
+    _cairo_output_stream_printf (surface->output,
+				 "%d 0 obj\n"
+				 "<< /Producer (cairo %s (https://cairographics.org))\n",
+				 surface->docinfo_res.id,
+				 cairo_version_string ());
+
+    if (ic->docinfo.title)
+	_cairo_output_stream_printf (surface->output, "   /Title %s\n", ic->docinfo.title);
+
+    if (ic->docinfo.author)
+	_cairo_output_stream_printf (surface->output, "   /Author %s\n", ic->docinfo.author);
+
+    if (ic->docinfo.subject)
+	_cairo_output_stream_printf (surface->output, "   /Subject %s\n", ic->docinfo.subject);
+
+    if (ic->docinfo.keywords)
+	_cairo_output_stream_printf (surface->output, "   /Keywords %s\n", ic->docinfo.keywords);
+
+    if (ic->docinfo.creator)
+	_cairo_output_stream_printf (surface->output, "   /Creator %s\n", ic->docinfo.creator);
+
+    if (ic->docinfo.create_date)
+	_cairo_output_stream_printf (surface->output, "   /CreationDate %s\n", ic->docinfo.create_date);
+
+    if (ic->docinfo.mod_date)
+	_cairo_output_stream_printf (surface->output, "   /ModDate %s\n", ic->docinfo.mod_date);
+
+    _cairo_output_stream_printf (surface->output,
+				 ">>\n"
+				 "endobj\n");
+
+    return CAIRO_STATUS_SUCCESS;
+}
+
+static cairo_int_status_t
+_cairo_pdf_interchange_begin_structure_tag (cairo_pdf_surface_t    *surface,
+					    cairo_tag_type_t        tag_type,
+					    const char             *name,
+					    const char             *attributes)
+{
+    int page_num, mcid;
+    cairo_int_status_t status = CAIRO_STATUS_SUCCESS;
+    cairo_pdf_interchange_t *ic = &surface->interchange;
+
+    if (surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE) {
+	status = add_tree_node (surface, ic->current_node, name, &ic->current_node);
+	if (unlikely (status))
+	    return status;
+
+	_cairo_tag_stack_set_top_data (&ic->analysis_tag_stack, ic->current_node);
+
+	if (tag_type & TAG_TYPE_LINK) {
+	    status = add_annotation (surface, ic->current_node, name, attributes);
+	    if (unlikely (status))
+		return status;
+
+	    cairo_list_add_tail (&ic->current_node->extents.link, &ic->extents_list);
+	}
+
+    } else if (surface->paginated_mode == CAIRO_PAGINATED_MODE_RENDER) {
+	ic->current_node = _cairo_tag_stack_top_elem (&ic->render_tag_stack)->data;
+	assert (ic->current_node != NULL);
+	if (is_leaf_node (ic->current_node)) {
+	    page_num = _cairo_array_num_elements (&surface->pages);
+	    add_mcid_to_node (surface, ic->current_node, page_num, &mcid);
+	    status = _cairo_pdf_operators_tag_begin (&surface->pdf_operators, name, mcid);
+	}
+    }
+
+    return status;
+}
+
+static cairo_int_status_t
+_cairo_pdf_interchange_begin_dest_tag (cairo_pdf_surface_t    *surface,
+				       cairo_tag_type_t        tag_type,
+				       const char             *name,
+				       const char             *attributes)
+{
+    cairo_pdf_named_dest_t *dest;
+    cairo_pdf_interchange_t *ic = &surface->interchange;
+    cairo_int_status_t status = CAIRO_STATUS_SUCCESS;
+
+    if (surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE) {
+	dest = calloc (1, sizeof (cairo_pdf_named_dest_t));
+	if (unlikely (dest == NULL))
+	    return _cairo_error (CAIRO_STATUS_NO_MEMORY);
+
+	status = _cairo_tag_parse_dest_attributes (attributes, &dest->attrs);
+	if (unlikely (status))
+	    return status;
+
+	dest->page = _cairo_array_num_elements (&surface->pages);
+	init_named_dest_key (dest);
+	status = _cairo_hash_table_insert (ic->named_dests, &dest->base);
+	if (unlikely (status))
+	    return status;
+
+	_cairo_tag_stack_set_top_data (&ic->analysis_tag_stack, dest);
+	cairo_list_add_tail (&dest->extents.link, &ic->extents_list);
+	ic->num_dests++;
+    }
+
+    return status;
+}
+
+cairo_int_status_t
+_cairo_pdf_interchange_tag_begin (cairo_pdf_surface_t    *surface,
+				  const char             *name,
+				  const char             *attributes)
+{
+    cairo_int_status_t status = CAIRO_STATUS_SUCCESS;
+    cairo_tag_type_t tag_type;
+    cairo_pdf_interchange_t *ic = &surface->interchange;
+    void *ptr;
+
+    if (surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE) {
+	status = _cairo_tag_stack_push (&ic->analysis_tag_stack, name, attributes);
+
+    } else if (surface->paginated_mode == CAIRO_PAGINATED_MODE_RENDER) {
+	status = _cairo_tag_stack_push (&ic->render_tag_stack, name, attributes);
+	_cairo_array_copy_element (&ic->push_data, ic->push_data_index++, &ptr);
+	_cairo_tag_stack_set_top_data (&ic->render_tag_stack, ptr);
+    }
+
+    if (unlikely (status))
+	return status;
+
+    tag_type = _cairo_tag_get_type (name);
+    if (tag_type & TAG_TYPE_STRUCTURE) {
+	status = _cairo_pdf_interchange_begin_structure_tag (surface, tag_type, name, attributes);
+	if (unlikely (status))
+	    return status;
+    }
+
+    if (tag_type & TAG_TYPE_DEST) {
+	status = _cairo_pdf_interchange_begin_dest_tag (surface, tag_type, name, attributes);
+	if (unlikely (status))
+	    return status;
+    }
+
+    if (surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE) {
+	ptr = _cairo_tag_stack_top_elem (&ic->analysis_tag_stack)->data;
+	status = _cairo_array_append (&ic->push_data, &ptr);
+    }
+
+    return status;
+}
+
+static cairo_int_status_t
+_cairo_pdf_interchange_end_structure_tag (cairo_pdf_surface_t    *surface,
+					  cairo_tag_type_t        tag_type,
+					  cairo_tag_stack_elem_t *elem)
+{
+    const cairo_pdf_struct_tree_node_t *node;
+    struct tag_extents *tag, *next;
+    cairo_pdf_interchange_t *ic = &surface->interchange;
+    cairo_int_status_t status = CAIRO_STATUS_SUCCESS;
+
+    assert (elem->data != NULL);
+    node = elem->data;
+    if (surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE) {
+	if (tag_type & TAG_TYPE_LINK) {
+	    cairo_list_foreach_entry_safe (tag, next, struct tag_extents,
+					   &ic->extents_list, link) {
+		if (tag == &node->extents) {
+		    cairo_list_del (&tag->link);
+		    break;
+		}
+	    }
+	}
+    } else if (surface->paginated_mode == CAIRO_PAGINATED_MODE_RENDER) {
+	if (is_leaf_node (ic->current_node)) {
+	    status = _cairo_pdf_operators_tag_end (&surface->pdf_operators);
+	    if (unlikely (status))
+		return status;
+	}
+    }
+
+    ic->current_node = ic->current_node->parent;
+    assert (ic->current_node != NULL);
+
+    return status;
+}
+
+static cairo_int_status_t
+_cairo_pdf_interchange_end_dest_tag (cairo_pdf_surface_t    *surface,
+				     cairo_tag_type_t        tag_type,
+				     cairo_tag_stack_elem_t *elem)
+{
+    struct tag_extents *tag, *next;
+    cairo_pdf_named_dest_t *dest;
+    cairo_pdf_interchange_t *ic = &surface->interchange;
+
+    if (surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE) {
+	assert (elem->data != NULL);
+	dest = (cairo_pdf_named_dest_t *) elem->data;
+	cairo_list_foreach_entry_safe (tag, next, struct tag_extents,
+					   &ic->extents_list, link) {
+	    if (tag == &dest->extents) {
+		cairo_list_del (&tag->link);
+		break;
+	    }
+	}
+    }
+
+    return CAIRO_STATUS_SUCCESS;
+}
+
+cairo_int_status_t
+_cairo_pdf_interchange_tag_end (cairo_pdf_surface_t *surface,
+				const char          *name)
+{
+    cairo_int_status_t status = CAIRO_STATUS_SUCCESS;
+    cairo_pdf_interchange_t *ic = &surface->interchange;
+    cairo_tag_type_t tag_type;
+    cairo_tag_stack_elem_t *elem;
+
+    if (surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE)
+	status = _cairo_tag_stack_pop (&ic->analysis_tag_stack, name, &elem);
+    else if (surface->paginated_mode == CAIRO_PAGINATED_MODE_RENDER)
+	status = _cairo_tag_stack_pop (&ic->render_tag_stack, name, &elem);
+
+    if (unlikely (status))
+	return status;
+
+    tag_type = _cairo_tag_get_type (name);
+    if (tag_type & TAG_TYPE_STRUCTURE) {
+	status = _cairo_pdf_interchange_end_structure_tag (surface, tag_type, elem);
+	if (unlikely (status))
+	    goto cleanup;
+    }
+
+    if (tag_type & TAG_TYPE_DEST) {
+	status = _cairo_pdf_interchange_end_dest_tag (surface, tag_type, elem);
+	if (unlikely (status))
+	    goto cleanup;
+    }
+
+  cleanup:
+    _cairo_tag_stack_free_elem (elem);
+
+    return status;
+}
+
+cairo_int_status_t
+_cairo_pdf_interchange_add_operation_extents (cairo_pdf_surface_t         *surface,
+					      const cairo_rectangle_int_t *extents)
+{
+    cairo_pdf_interchange_t *ic = &surface->interchange;
+    struct tag_extents *tag;
+
+    if (surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE) {
+	cairo_list_foreach_entry (tag, struct tag_extents, &ic->extents_list, link) {
+	    if (tag->valid) {
+		_cairo_rectangle_union (&tag->extents, extents);
+	    } else {
+		tag->extents = *extents;
+		tag->valid = TRUE;
+	    }
+	}
+    }
+
+    return CAIRO_STATUS_SUCCESS;
+}
+
+cairo_int_status_t
+_cairo_pdf_interchange_begin_page_content (cairo_pdf_surface_t *surface)
+{
+    cairo_pdf_interchange_t *ic = &surface->interchange;
+    cairo_int_status_t status = CAIRO_STATUS_SUCCESS;
+    int page_num, mcid;
+
+    if (surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE) {
+	_cairo_array_truncate (&ic->mcid_to_tree, 0);
+	_cairo_array_truncate (&ic->push_data, 0);
+	ic->begin_page_node = ic->current_node;
+    } else if (surface->paginated_mode == CAIRO_PAGINATED_MODE_RENDER) {
+	ic->push_data_index = 0;
+	ic->current_node = ic->begin_page_node;
+	if (ic->end_page_node && is_leaf_node (ic->end_page_node)) {
+	    page_num = _cairo_array_num_elements (&surface->pages);
+	    add_mcid_to_node (surface, ic->end_page_node, page_num, &mcid);
+	    status = _cairo_pdf_operators_tag_begin (&surface->pdf_operators,
+						     ic->end_page_node->name,
+						     mcid);
+	}
+    }
+
+    return status;
+}
+
+cairo_int_status_t
+_cairo_pdf_interchange_end_page_content (cairo_pdf_surface_t *surface)
+{
+    cairo_pdf_interchange_t *ic = &surface->interchange;
+    cairo_int_status_t status = CAIRO_STATUS_SUCCESS;
+
+    if (surface->paginated_mode == CAIRO_PAGINATED_MODE_RENDER) {
+	ic->end_page_node = ic->current_node;
+	if (is_leaf_node (ic->current_node))
+	    status = _cairo_pdf_operators_tag_end (&surface->pdf_operators);
+    }
+
+    return status;
+}
+
+cairo_int_status_t
+_cairo_pdf_interchange_write_page_objects (cairo_pdf_surface_t *surface)
+{
+    cairo_int_status_t status;
+
+    status = cairo_pdf_interchange_write_page_annots (surface);
+     if (unlikely (status))
+	return status;
+
+     cairo_pdf_interchange_clear_annotations (surface);
+
+    return cairo_pdf_interchange_write_page_parent_elems (surface);
+}
+
+cairo_int_status_t
+_cairo_pdf_interchange_write_document_objects (cairo_pdf_surface_t *surface)
+{
+    cairo_pdf_interchange_t *ic = &surface->interchange;
+    cairo_int_status_t status = CAIRO_STATUS_SUCCESS;
+    cairo_tag_stack_structure_type_t tag_type;
+
+    tag_type = _cairo_tag_stack_get_structure_type (&ic->analysis_tag_stack);
+    if (tag_type == TAG_TREE_TYPE_TAGGED || tag_type == TAG_TREE_TYPE_STRUCTURE) {
+
+	status = cairo_pdf_interchange_write_parent_tree (surface);
+	if (unlikely (status))
+	    return status;
+
+	status = cairo_pdf_interchange_write_struct_tree (surface);
+	if (unlikely (status))
+	    return status;
+
+	if (tag_type == TAG_TREE_TYPE_TAGGED)
+	    surface->tagged = TRUE;
+    }
+
+    status = cairo_pdf_interchange_write_outline (surface);
+    if (unlikely (status))
+	return status;
+
+    status = cairo_pdf_interchange_write_page_labels (surface);
+    if (unlikely (status))
+	return status;
+
+    status = cairo_pdf_interchange_write_names_dict (surface);
+    if (unlikely (status))
+	return status;
+
+    status = cairo_pdf_interchange_write_docinfo (surface);
+
+    return status;
+}
+
+static void
+_cairo_pdf_interchange_set_create_date (cairo_pdf_surface_t *surface)
+{
+    time_t utc, local, offset;
+    struct tm tm_local, tm_utc;
+    char buf[50];
+    int buf_size;
+    char *p;
+    cairo_pdf_interchange_t *ic = &surface->interchange;
+
+    utc = time (NULL);
+    localtime_r (&utc, &tm_local);
+    strftime (buf, sizeof(buf), "(D:%Y%m%d%H%M%S", &tm_local);
+
+    /* strftime "%z" is non standard and does not work on windows (it prints zone name, not offset).
+     * Calculate time zone offset by comparing local and utc time_t values for the same time.
+     */
+    gmtime_r (&utc, &tm_utc);
+    tm_utc.tm_isdst = tm_local.tm_isdst;
+    local = mktime (&tm_utc);
+    offset = difftime (utc, local);
+
+    if (offset == 0) {
+	strcat (buf, "Z");
+    } else {
+	if (offset > 0) {
+	    strcat (buf, "+");
+	} else {
+	    strcat (buf, "-");
+	    offset = -offset;
+	}
+	p = buf + strlen (buf);
+	buf_size = sizeof (buf) - strlen (buf);
+	snprintf (p, buf_size, "%02d'%02d", (int)(offset/3600), (int)(offset%3600)/60);
+    }
+    strcat (buf, ")");
+    ic->docinfo.create_date = strdup (buf);
+}
+
+cairo_int_status_t
+_cairo_pdf_interchange_init (cairo_pdf_surface_t *surface)
+{
+    cairo_pdf_interchange_t *ic = &surface->interchange;
+    cairo_pdf_outline_entry_t *outline_root;
+    cairo_int_status_t status;
+
+    _cairo_tag_stack_init (&ic->analysis_tag_stack);
+    _cairo_tag_stack_init (&ic->render_tag_stack);
+    _cairo_array_init (&ic->push_data, sizeof(void *));
+    ic->struct_root = calloc (1, sizeof(cairo_pdf_struct_tree_node_t));
+    if (unlikely (ic->struct_root == NULL))
+	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
+
+    cairo_list_init (&ic->struct_root->children);
+    _cairo_array_init (&ic->struct_root->mcid, sizeof(struct page_mcid));
+    ic->current_node = ic->struct_root;
+    ic->begin_page_node = NULL;
+    ic->end_page_node = NULL;
+    _cairo_array_init (&ic->parent_tree, sizeof(cairo_pdf_resource_t));
+    _cairo_array_init (&ic->mcid_to_tree, sizeof(cairo_pdf_struct_tree_node_t *));
+    _cairo_array_init (&ic->annots, sizeof(cairo_pdf_annotation_t *));
+    ic->parent_tree_res.id = 0;
+    cairo_list_init (&ic->extents_list);
+    ic->named_dests = _cairo_hash_table_create (_named_dest_equal);
+    if (unlikely (ic->named_dests == NULL))
+	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
+
+    ic->num_dests = 0;
+    ic->sorted_dests = NULL;
+    ic->dests_res.id = 0;
+
+    _cairo_array_init (&ic->outline, sizeof(cairo_pdf_outline_entry_t *));
+    outline_root = calloc (1, sizeof(cairo_pdf_outline_entry_t));
+    if (unlikely (outline_root == NULL))
+	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
+
+    memset (&ic->docinfo, 0, sizeof (ic->docinfo));
+    _cairo_pdf_interchange_set_create_date (surface);
+    status = _cairo_array_append (&ic->outline, &outline_root);
+
+    return status;
+}
+
+static void
+_cairo_pdf_interchange_free_outlines (cairo_pdf_surface_t *surface)
+{
+    cairo_pdf_interchange_t *ic = &surface->interchange;
+    int num_elems, i;
+
+    num_elems = _cairo_array_num_elements (&ic->outline);
+    for (i = 0; i < num_elems; i++) {
+	cairo_pdf_outline_entry_t *outline;
+
+	_cairo_array_copy_element (&ic->outline, i, &outline);
+	free (outline->name);
+	free (outline->link_attrs.dest);
+	free (outline->link_attrs.uri);
+	free (outline->link_attrs.file);
+	free (outline);
+    }
+    _cairo_array_fini (&ic->outline);
+}
+
+cairo_int_status_t
+_cairo_pdf_interchange_fini (cairo_pdf_surface_t *surface)
+{
+    cairo_pdf_interchange_t *ic = &surface->interchange;
+
+    _cairo_tag_stack_fini (&ic->analysis_tag_stack);
+    _cairo_tag_stack_fini (&ic->render_tag_stack);
+    _cairo_array_fini (&ic->push_data);
+    free_node (ic->struct_root);
+    _cairo_array_fini (&ic->mcid_to_tree);
+    cairo_pdf_interchange_clear_annotations (surface);
+    _cairo_array_fini (&ic->annots);
+    _cairo_array_fini (&ic->parent_tree);
+    _cairo_hash_table_foreach (ic->named_dests, _named_dest_pluck, ic->named_dests);
+    _cairo_hash_table_destroy (ic->named_dests);
+    free (ic->sorted_dests);
+    _cairo_pdf_interchange_free_outlines (surface);
+    free (ic->docinfo.title);
+    free (ic->docinfo.author);
+    free (ic->docinfo.subject);
+    free (ic->docinfo.keywords);
+    free (ic->docinfo.creator);
+    free (ic->docinfo.create_date);
+    free (ic->docinfo.mod_date);
+
+    return CAIRO_STATUS_SUCCESS;
+}
+
+cairo_int_status_t
+_cairo_pdf_interchange_add_outline (cairo_pdf_surface_t        *surface,
+				    int                         parent_id,
+				    const char                 *name,
+				    const char                 *link_attribs,
+				    cairo_pdf_outline_flags_t   flags,
+				    int                        *id)
+{
+    cairo_pdf_interchange_t *ic = &surface->interchange;
+    cairo_pdf_outline_entry_t *outline;
+    cairo_pdf_outline_entry_t *parent;
+    cairo_int_status_t status;
+
+    if (parent_id < 0 || parent_id >= (int)_cairo_array_num_elements (&ic->outline))
+	return CAIRO_STATUS_SUCCESS;
+
+    outline = _cairo_malloc (sizeof(cairo_pdf_outline_entry_t));
+    if (unlikely (outline == NULL))
+	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
+
+    status = _cairo_tag_parse_link_attributes (link_attribs, &outline->link_attrs);
+    if (unlikely (status)) {
+	free (outline);
+	return status;
+    }
+
+    outline->res = _cairo_pdf_surface_new_object (surface);
+    if (outline->res.id == 0)
+	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
+
+    outline->name = strdup (name);
+    outline->flags = flags;
+    outline->count = 0;
+
+    _cairo_array_copy_element (&ic->outline, parent_id, &parent);
+
+    outline->parent = parent;
+    outline->first_child = NULL;
+    outline->last_child = NULL;
+    outline->next = NULL;
+    if (parent->last_child) {
+	parent->last_child->next = outline;
+	outline->prev = parent->last_child;
+	parent->last_child = outline;
+    } else {
+	parent->first_child = outline;
+	parent->last_child = outline;
+	outline->prev = NULL;
+    }
+
+    *id = _cairo_array_num_elements (&ic->outline);
+    status = _cairo_array_append (&ic->outline, &outline);
+    if (unlikely (status))
+	return status;
+
+    /* Update Count */
+    outline = outline->parent;
+    while (outline) {
+	if (outline->flags & CAIRO_PDF_OUTLINE_FLAG_OPEN) {
+	    outline->count++;
+	} else {
+	    outline->count--;
+	    break;
+	}
+	outline = outline->parent;
+    }
+
+    return CAIRO_STATUS_SUCCESS;
+}
+
+/*
+ * Date must be in the following format:
+ *
+ *     YYYY-MM-DDThh:mm:ss[Z+-]hh:mm
+ *
+ * Only the year is required. If a field is included all preceding
+ * fields must be included.
+ */
+static char *
+iso8601_to_pdf_date_string (const char *iso)
+{
+    char buf[40];
+    const char *p;
+    int i;
+
+    /* Check that utf8 contains only the characters "0123456789-T:Z+" */
+    p = iso;
+    while (*p) {
+       if (!_cairo_isdigit (*p) && *p != '-' && *p != 'T' &&
+           *p != ':' && *p != 'Z' && *p != '+')
+           return NULL;
+       p++;
+    }
+
+    p = iso;
+    strcpy (buf, "(");
+
+   /* YYYY (required) */
+    if (strlen (p) < 4)
+       return NULL;
+
+    strncat (buf, p, 4);
+    p += 4;
+
+    /* -MM, -DD, Thh, :mm, :ss */
+    for (i = 0; i < 5; i++) {
+	if (strlen (p) < 3)
+	    goto finish;
+
+	strncat (buf, p + 1, 2);
+	p += 3;
+    }
+
+    /* Z, +, - */
+    if (strlen (p) < 1)
+       goto finish;
+    strncat (buf, p, 1);
+    p += 1;
+
+    /* hh */
+    if (strlen (p) < 2)
+	goto finish;
+
+    strncat (buf, p, 2);
+    strcat (buf, "'");
+    p += 2;
+
+    /* :mm */
+    if (strlen (p) < 3)
+	goto finish;
+
+    strncat (buf, p + 1, 3);
+
+  finish:
+    strcat (buf, ")");
+    return strdup (buf);
+}
+
+cairo_int_status_t
+_cairo_pdf_interchange_set_metadata (cairo_pdf_surface_t  *surface,
+				     cairo_pdf_metadata_t  metadata,
+				     const char           *utf8)
+{
+    cairo_pdf_interchange_t *ic = &surface->interchange;
+    cairo_status_t status;
+    char *s = NULL;
+
+    if (utf8) {
+	if (metadata == CAIRO_PDF_METADATA_CREATE_DATE ||
+	    metadata == CAIRO_PDF_METADATA_MOD_DATE) {
+	    s = iso8601_to_pdf_date_string (utf8);
+	} else {
+	    status = _cairo_utf8_to_pdf_string (utf8, &s);
+	    if (unlikely (status))
+		return status;
+	}
+    }
+
+    switch (metadata) {
+	case CAIRO_PDF_METADATA_TITLE:
+	    free (ic->docinfo.title);
+	    ic->docinfo.title = s;
+	    break;
+	case CAIRO_PDF_METADATA_AUTHOR:
+	    free (ic->docinfo.author);
+	    ic->docinfo.author = s;
+	    break;
+	case CAIRO_PDF_METADATA_SUBJECT:
+	    free (ic->docinfo.subject);
+	    ic->docinfo.subject = s;
+	    break;
+	case CAIRO_PDF_METADATA_KEYWORDS:
+	    free (ic->docinfo.keywords);
+	    ic->docinfo.keywords = s;
+	    break;
+	case CAIRO_PDF_METADATA_CREATOR:
+	    free (ic->docinfo.creator);
+	    ic->docinfo.creator = s;
+	    break;
+	case CAIRO_PDF_METADATA_CREATE_DATE:
+	    free (ic->docinfo.create_date);
+	    ic->docinfo.create_date = s;
+	    break;
+	case CAIRO_PDF_METADATA_MOD_DATE:
+	    free (ic->docinfo.mod_date);
+	    ic->docinfo.mod_date = s;
+	    break;
+    }
+
+    return CAIRO_STATUS_SUCCESS;
+}


Property changes on: trunk/Build/source/libs/cairo/cairo-src/src/cairo-pdf-interchange.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+LF
\ No newline at end of property
Modified: trunk/Build/source/libs/cairo/cairo-src/src/cairo-pdf-operators-private.h
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/src/cairo-pdf-operators-private.h	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/src/cairo-pdf-operators-private.h	2018-10-20 03:19:36 UTC (rev 48952)
@@ -173,4 +173,12 @@
 				       cairo_text_cluster_flags_t  cluster_flags,
 				       cairo_scaled_font_t	  *scaled_font);
 
+cairo_private cairo_int_status_t
+_cairo_pdf_operators_tag_begin (cairo_pdf_operators_t *pdf_operators,
+				const char            *tag_name,
+				int                    mcid);
+
+cairo_private cairo_int_status_t
+_cairo_pdf_operators_tag_end (cairo_pdf_operators_t *pdf_operators);
+
 #endif /* CAIRO_PDF_OPERATORS_H */

Modified: trunk/Build/source/libs/cairo/cairo-src/src/cairo-pdf-operators.c
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/src/cairo-pdf-operators.c	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/src/cairo-pdf-operators.c	2018-10-20 03:19:36 UTC (rev 48952)
@@ -140,7 +140,7 @@
  * assumptions will be made about the state. The next time a
  * particular graphics state is required (eg line width) the state
  * operator is always emitted and then remembered for subsequent
- * operatations.
+ * operations.
  *
  * This should be called when starting a new stream or after emitting
  * the 'Q' operator (where pdf-operators functions were called inside
@@ -359,7 +359,7 @@
     if (output->status)
 	return _cairo_output_stream_create_in_error (output->status);
 
-    stream = malloc (sizeof (word_wrap_stream_t));
+    stream = _cairo_malloc (sizeof (word_wrap_stream_t));
     if (unlikely (stream == NULL)) {
 	_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
 	return (cairo_output_stream_t *) &_cairo_output_stream_nil;
@@ -1493,9 +1493,6 @@
     cairo_matrix_init_scale (&invert_y_axis, 1, -1);
     text_matrix = scaled_font->scale;
 
-    /* Invert y axis in font space  */
-    cairo_matrix_multiply (&text_matrix, &text_matrix, &invert_y_axis);
-
     /* Invert y axis in device space  */
     cairo_matrix_multiply (&text_matrix, &invert_y_axis, &text_matrix);
 
@@ -1558,4 +1555,41 @@
     return _cairo_output_stream_get_status (pdf_operators->stream);
 }
 
+cairo_int_status_t
+_cairo_pdf_operators_tag_begin (cairo_pdf_operators_t *pdf_operators,
+				const char            *tag_name,
+				int                    mcid)
+{
+    cairo_status_t status;
+
+    if (pdf_operators->in_text_object) {
+	status = _cairo_pdf_operators_end_text (pdf_operators);
+	if (unlikely (status))
+	    return status;
+    }
+
+    _cairo_output_stream_printf (pdf_operators->stream,
+				 "/%s << /MCID %d >> BDC\n",
+				 tag_name,
+				 mcid);
+
+    return _cairo_output_stream_get_status (pdf_operators->stream);
+}
+
+cairo_int_status_t
+_cairo_pdf_operators_tag_end (cairo_pdf_operators_t *pdf_operators)
+{
+    cairo_status_t status;
+
+    if (pdf_operators->in_text_object) {
+	status = _cairo_pdf_operators_end_text (pdf_operators);
+	if (unlikely (status))
+	    return status;
+    }
+
+    _cairo_output_stream_printf (pdf_operators->stream, "EMC\n");
+
+    return _cairo_output_stream_get_status (pdf_operators->stream);
+}
+
 #endif /* CAIRO_HAS_PDF_OPERATORS */

Modified: trunk/Build/source/libs/cairo/cairo-src/src/cairo-pdf-shading.c
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/src/cairo-pdf-shading.c	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/src/cairo-pdf-shading.c	2018-10-20 03:19:36 UTC (rev 48952)
@@ -170,7 +170,7 @@
      * 4 colors. Each color is stored in 2 bytes * num_color_components.
      */
     shading->data_length = num_patches * (1 + 16 * 2 * 4 + 4 * 2 * num_color_components);
-    shading->data = malloc (shading->data_length);
+    shading->data = _cairo_malloc (shading->data_length);
     if (unlikely (shading->data == NULL))
 	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 

Modified: trunk/Build/source/libs/cairo/cairo-src/src/cairo-pdf-surface-private.h
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/src/cairo-pdf-surface-private.h	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/src/cairo-pdf-surface-private.h	2018-10-20 03:19:36 UTC (rev 48952)
@@ -48,6 +48,8 @@
 #include "cairo-surface-clipper-private.h"
 #include "cairo-pdf-operators-private.h"
 #include "cairo-path-fixed-private.h"
+#include "cairo-tag-attributes-private.h"
+#include "cairo-tag-stack-private.h"
 
 typedef struct _cairo_pdf_resource {
     unsigned int id;
@@ -74,11 +76,19 @@
     cairo_bool_t interpolate;
     cairo_bool_t stencil_mask;
     cairo_bool_t smask;
+    cairo_bool_t need_transp_group;
     cairo_pdf_resource_t surface_res;
     cairo_pdf_resource_t smask_res;
-    int width;
-    int height;
+
+    /* True if surface will be emitted as an Image XObject. */
+    cairo_bool_t emit_image;
+
+    /* Extents of the source surface. */
+    cairo_bool_t bounded;
     cairo_rectangle_int_t extents;
+
+    /* Union of source extents required for all operations using this source */
+    cairo_rectangle_int_t required_extents;
 } cairo_pdf_source_surface_entry_t;
 
 typedef struct _cairo_pdf_source_surface {
@@ -97,6 +107,17 @@
     cairo_pdf_resource_t gstate_res;
     cairo_operator_t operator;
     cairo_bool_t is_shading;
+
+    /* PDF pattern space is the pattern matrix concatenated with the
+     * initial space of the parent object. If the parent object is the
+     * page, the initial space does not include the Y-axis flipping
+     * matrix emitted at the start of the page content stream.  If the
+     * parent object is not the page content stream, the initial space
+     * will have a flipped Y-axis. The inverted_y_axis flag is true
+     * when the initial space of the parent object that is drawing
+     * this pattern has a flipped Y-axis.
+     */
+    cairo_bool_t inverted_y_axis;
 } cairo_pdf_pattern_t;
 
 typedef enum _cairo_pdf_operation {
@@ -138,6 +159,91 @@
     cairo_bool_t emitted;
 } cairo_pdf_jbig2_global_t;
 
+/* cairo-pdf-interchange.c types */
+
+struct page_mcid {
+    int page;
+    int mcid;
+};
+
+struct tag_extents {
+    cairo_rectangle_int_t extents;
+    cairo_bool_t valid;
+    cairo_list_t link;
+};
+
+typedef struct _cairo_pdf_struct_tree_node {
+    char *name;
+    cairo_pdf_resource_t res;
+    struct _cairo_pdf_struct_tree_node *parent;
+    cairo_list_t children;
+    cairo_array_t mcid; /* array of struct page_mcid */
+    cairo_pdf_resource_t annot_res; /* 0 if no annot */
+    struct tag_extents extents;
+    cairo_list_t link;
+} cairo_pdf_struct_tree_node_t;
+
+typedef struct _cairo_pdf_annotation {
+    cairo_pdf_struct_tree_node_t *node; /* node containing the annotation */
+    cairo_link_attrs_t link_attrs;
+} cairo_pdf_annotation_t;
+
+typedef struct _cairo_pdf_named_dest {
+    cairo_hash_entry_t base;
+    struct tag_extents extents;
+    cairo_dest_attrs_t attrs;
+    int page;
+} cairo_pdf_named_dest_t;
+
+typedef struct _cairo_pdf_outline_entry {
+    char *name;
+    cairo_link_attrs_t link_attrs;
+    cairo_pdf_outline_flags_t flags;
+    cairo_pdf_resource_t res;
+    struct _cairo_pdf_outline_entry *parent;
+    struct _cairo_pdf_outline_entry *first_child;
+    struct _cairo_pdf_outline_entry *last_child;
+    struct _cairo_pdf_outline_entry *next;
+    struct _cairo_pdf_outline_entry *prev;
+    int count;
+} cairo_pdf_outline_entry_t;
+
+struct docinfo {
+    char *title;
+    char *author;
+    char *subject;
+    char *keywords;
+    char *creator;
+    char *create_date;
+    char *mod_date;
+};
+
+typedef struct _cairo_pdf_interchange {
+    cairo_tag_stack_t analysis_tag_stack;
+    cairo_tag_stack_t render_tag_stack;
+    cairo_array_t push_data; /* records analysis_tag_stack data field for each push */
+    int push_data_index;
+    cairo_pdf_struct_tree_node_t *struct_root;
+    cairo_pdf_struct_tree_node_t *current_node;
+    cairo_pdf_struct_tree_node_t *begin_page_node;
+    cairo_pdf_struct_tree_node_t *end_page_node;
+    cairo_array_t parent_tree; /* parent tree resources */
+    cairo_array_t mcid_to_tree; /* mcid to tree node mapping for current page */
+    cairo_array_t annots; /* array of pointers to cairo_pdf_annotation_t */
+    cairo_pdf_resource_t parent_tree_res;
+    cairo_list_t extents_list;
+    cairo_hash_table_t *named_dests;
+    int num_dests;
+    cairo_pdf_named_dest_t **sorted_dests;
+    cairo_pdf_resource_t dests_res;
+    int annot_page;
+    cairo_array_t outline; /* array of pointers to cairo_pdf_outline_entry_t; */
+    struct docinfo docinfo;
+
+} cairo_pdf_interchange_t;
+
+/* pdf surface data */
+
 typedef struct _cairo_pdf_surface cairo_pdf_surface_t;
 
 struct _cairo_pdf_surface {
@@ -149,7 +255,10 @@
 
     double width;
     double height;
+    cairo_rectangle_int_t surface_extents;
+    cairo_bool_t surface_bounded;
     cairo_matrix_t cairo_to_pdf;
+    cairo_bool_t in_xobject;
 
     cairo_array_t objects;
     cairo_array_t pages;
@@ -157,10 +266,12 @@
     cairo_array_t alpha_linear_functions;
     cairo_array_t page_patterns;
     cairo_array_t page_surfaces;
+    cairo_array_t doc_surfaces;
     cairo_hash_table_t *all_surfaces;
     cairo_array_t smask_groups;
     cairo_array_t knockout_group;
     cairo_array_t jbig2_global;
+    cairo_array_t page_heights;
 
     cairo_scaled_font_subsets_t *font_subsets;
     cairo_array_t fonts;
@@ -167,6 +278,7 @@
 
     cairo_pdf_resource_t next_available_resource;
     cairo_pdf_resource_t pages_resource;
+    cairo_pdf_resource_t struct_tree_root;
 
     cairo_pdf_version_t pdf_version;
     cairo_bool_t compress_content;
@@ -212,7 +324,76 @@
     double current_color_blue;
     double current_color_alpha;
 
+    cairo_pdf_interchange_t interchange;
+    int page_parent_tree; /* -1 if not used */
+    cairo_array_t page_annots;
+    cairo_bool_t tagged;
+    char *current_page_label;
+    cairo_array_t page_labels;
+    cairo_pdf_resource_t outlines_dict_res;
+    cairo_pdf_resource_t names_dict_res;
+    cairo_pdf_resource_t docinfo_res;
+    cairo_pdf_resource_t page_labels_res;
+
+    int thumbnail_width;
+    int thumbnail_height;
+    cairo_image_surface_t *thumbnail_image;
+
     cairo_surface_t *paginated_surface;
 };
 
+cairo_private cairo_pdf_resource_t
+_cairo_pdf_surface_new_object (cairo_pdf_surface_t *surface);
+
+cairo_private void
+_cairo_pdf_surface_update_object (cairo_pdf_surface_t	*surface,
+				  cairo_pdf_resource_t	 resource);
+
+cairo_private cairo_int_status_t
+_cairo_utf8_to_pdf_string (const char *utf8, char **str_out);
+
+cairo_private cairo_int_status_t
+_cairo_pdf_interchange_init (cairo_pdf_surface_t *surface);
+
+cairo_private cairo_int_status_t
+_cairo_pdf_interchange_fini (cairo_pdf_surface_t *surface);
+
+cairo_private cairo_int_status_t
+_cairo_pdf_interchange_begin_page_content (cairo_pdf_surface_t *surface);
+
+cairo_private cairo_int_status_t
+_cairo_pdf_interchange_end_page_content (cairo_pdf_surface_t *surface);
+
+cairo_private cairo_int_status_t
+_cairo_pdf_interchange_tag_begin (cairo_pdf_surface_t    *surface,
+				  const char             *name,
+				  const char             *attributes);
+
+cairo_private cairo_int_status_t
+_cairo_pdf_interchange_tag_end (cairo_pdf_surface_t *surface,
+				const char          *name);
+
+cairo_private cairo_int_status_t
+_cairo_pdf_interchange_add_operation_extents (cairo_pdf_surface_t         *surface,
+					      const cairo_rectangle_int_t *extents);
+
+cairo_private cairo_int_status_t
+_cairo_pdf_interchange_write_page_objects (cairo_pdf_surface_t *surface);
+
+cairo_private cairo_int_status_t
+_cairo_pdf_interchange_write_document_objects (cairo_pdf_surface_t *surface);
+
+cairo_private cairo_int_status_t
+_cairo_pdf_interchange_add_outline (cairo_pdf_surface_t        *surface,
+				    int                         parent_id,
+				    const char                 *name,
+				    const char                 *dest,
+				    cairo_pdf_outline_flags_t   flags,
+				    int                        *id);
+
+cairo_private cairo_int_status_t
+_cairo_pdf_interchange_set_metadata (cairo_pdf_surface_t  *surface,
+				     cairo_pdf_metadata_t  metadata,
+				     const char           *utf8);
+
 #endif /* CAIRO_PDF_SURFACE_PRIVATE_H */

Modified: trunk/Build/source/libs/cairo/cairo-src/src/cairo-pdf-surface.c
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/src/cairo-pdf-surface.c	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/src/cairo-pdf-surface.c	2018-10-20 03:19:36 UTC (rev 48952)
@@ -63,18 +63,8 @@
 #include "cairo-surface-subsurface-private.h"
 #include "cairo-type3-glyph-surface-private.h"
 
-#include <time.h>
 #include <zlib.h>
 
-/* Issues:
- *
- * - We embed an image in the stream each time it's composited.  We
- *   could add generation counters to surfaces and remember the stream
- *   ID for a particular generation for a particular surface.
- *
- * - Backend specific meta data.
- */
-
 /*
  * Page Structure of the Generated PDF:
  *
@@ -134,8 +124,10 @@
  * The following mime types are supported: %CAIRO_MIME_TYPE_JPEG,
  * %CAIRO_MIME_TYPE_JP2, %CAIRO_MIME_TYPE_UNIQUE_ID,
  * %CAIRO_MIME_TYPE_JBIG2, %CAIRO_MIME_TYPE_JBIG2_GLOBAL,
- * %CAIRO_MIME_TYPE_JBIG2_GLOBAL_ID.
+ * %CAIRO_MIME_TYPE_JBIG2_GLOBAL_ID,
+ * %CAIRO_MIME_TYPE_CCITT_FAX, %CAIRO_MIME_TYPE_CCITT_FAX_PARAMS.
  *
+ * # JBIG2 Images #
  * JBIG2 data in PDF must be in the embedded format as described in
  * ISO/IEC 11544. Image specific JBIG2 data must be in
  * %CAIRO_MIME_TYPE_JBIG2.  Any global segments in the JBIG2 data
@@ -142,11 +134,52 @@
  * (segments with page association field set to 0) must be in
  * %CAIRO_MIME_TYPE_JBIG2_GLOBAL. The global data may be shared by
  * multiple images. All images sharing the same global data must set
- * %CAIRO_MIME_TYPE_JBIG2_GLOBAL_ID to a unique identifer. At least
+ * %CAIRO_MIME_TYPE_JBIG2_GLOBAL_ID to a unique identifier. At least
  * one of the images must provide the global data using
  * %CAIRO_MIME_TYPE_JBIG2_GLOBAL. The global data will only be
- * embedded once but shared by all JBIG2 images with the same
+ * embedded once and shared by all JBIG2 images with the same
  * %CAIRO_MIME_TYPE_JBIG2_GLOBAL_ID.
+ *
+ * # CCITT Fax Images # {#ccitt}
+ * The %CAIRO_MIME_TYPE_CCITT_FAX mime data requires a number of decoding
+ * parameters These parameters are specified using %CAIRO_MIME_TYPE_CCITT_FAX_PARAMS.
+ *
+ * %CAIRO_MIME_TYPE_CCITT_FAX_PARAMS mime data must contain a string of the form
+ * "param1=value1 param2=value2 ...".
+ *
+ * @Columns: [required] An integer specifying the width of the image in pixels.
+ *
+ * @Rows: [required] An integer specifying the height of the image in scan lines.
+ *
+ * @K: [optional] An integer identifying the encoding scheme used. < 0
+ * is 2 dimensional Group 4, = 0 is Group3 1 dimensional, > 0 is mixed 1
+ * and 2 dimensional encoding. Default is 0.
+ *
+ * @EndOfLine: [optional] If true end-of-line bit patterns are present. Default is false.
+ *
+ * @EncodedByteAlign: [optional] If true the end of line is padded
+ * with 0 bits so the next line begins on a byte boundary. Default is false.
+ *
+ * @EndOfBlock: [optional] If true the data contains an end-of-block pattern. Default is true.
+ *
+ * @BlackIs1: [optional] If true 1 bits are black pixels. Default is false.
+ *
+ * @DamagedRowsBeforeError: [optional] An integer specifying the
+ * number of damages rows tolerated before an error occurs. Default is 0.
+ *
+ * Boolean values may be "true" or "false", or 1 or 0.
+ *
+ * These parameters are the same as the CCITTFaxDecode parameters in the
+ * [PostScript Language Reference](https://www.adobe.com/products/postscript/pdfs/PLRM.pdf)
+ * and [Portable Document Format (PDF)](https://www.adobe.com/content/dam/Adobe/en/devnet/pdf/pdfs/PDF32000_2008.pdf).
+ * Refer to these documents for further details.
+ *
+ * An example %CAIRO_MIME_TYPE_CCITT_FAX_PARAMS string is:
+ *
+ * <programlisting>
+ * "Columns=10230 Rows=40000 K=1 EndOfLine=true EncodedByteAlign=1 BlackIs1=false"
+ * </programlisting>
+ *
  **/
 
 static cairo_bool_t
@@ -184,6 +217,8 @@
     CAIRO_MIME_TYPE_JBIG2,
     CAIRO_MIME_TYPE_JBIG2_GLOBAL,
     CAIRO_MIME_TYPE_JBIG2_GLOBAL_ID,
+    CAIRO_MIME_TYPE_CCITT_FAX,
+    CAIRO_MIME_TYPE_CCITT_FAX_PARAMS,
     NULL
 };
 
@@ -209,9 +244,6 @@
     double               alpha2;
 } cairo_pdf_alpha_linear_function_t;
 
-static cairo_pdf_resource_t
-_cairo_pdf_surface_new_object (cairo_pdf_surface_t *surface);
-
 static void
 _cairo_pdf_surface_clear (cairo_pdf_surface_t *surface);
 
@@ -236,6 +268,12 @@
 _cairo_pdf_surface_close_stream (cairo_pdf_surface_t	*surface);
 
 static cairo_int_status_t
+_cairo_pdf_surface_emit_surface (cairo_pdf_surface_t        *surface,
+				 cairo_pdf_source_surface_t *source,
+				 cairo_bool_t                test,
+				 cairo_bool_t               *is_image);
+
+static cairo_int_status_t
 _cairo_pdf_surface_write_page (cairo_pdf_surface_t *surface);
 
 static void
@@ -242,9 +280,6 @@
 _cairo_pdf_surface_write_pages (cairo_pdf_surface_t *surface);
 
 static cairo_pdf_resource_t
-_cairo_pdf_surface_write_info (cairo_pdf_surface_t *surface);
-
-static cairo_pdf_resource_t
 _cairo_pdf_surface_write_catalog (cairo_pdf_surface_t *surface);
 
 static long
@@ -251,6 +286,10 @@
 _cairo_pdf_surface_write_xref (cairo_pdf_surface_t *surface);
 
 static cairo_int_status_t
+_cairo_pdf_surface_write_patterns_and_smask_groups (cairo_pdf_surface_t *surface,
+						    cairo_bool_t         finish);
+
+static cairo_int_status_t
 _cairo_pdf_surface_write_page (cairo_pdf_surface_t *surface);
 
 static cairo_int_status_t
@@ -262,7 +301,7 @@
 static const cairo_surface_backend_t cairo_pdf_surface_backend;
 static const cairo_paginated_surface_backend_t cairo_pdf_surface_paginated_backend;
 
-static cairo_pdf_resource_t
+cairo_pdf_resource_t
 _cairo_pdf_surface_new_object (cairo_pdf_surface_t *surface)
 {
     cairo_pdf_resource_t resource;
@@ -283,7 +322,7 @@
     return resource;
 }
 
-static void
+void
 _cairo_pdf_surface_update_object (cairo_pdf_surface_t	*surface,
 				  cairo_pdf_resource_t	 resource)
 {
@@ -300,9 +339,10 @@
 {
     surface->width = width;
     surface->height = height;
-    cairo_matrix_init (&surface->cairo_to_pdf, 1, 0, 0, -1, 0, height);
-    _cairo_pdf_operators_set_cairo_to_pdf_matrix (&surface->pdf_operators,
-						  &surface->cairo_to_pdf);
+    surface->surface_extents.x = 0;
+    surface->surface_extents.y = 0;
+    surface->surface_extents.width  = ceil (surface->width);
+    surface->surface_extents.height = ceil (surface->height);
 }
 
 static cairo_bool_t
@@ -357,7 +397,7 @@
     cairo_pdf_surface_t *surface;
     cairo_status_t status, status_ignored;
 
-    surface = malloc (sizeof (cairo_pdf_surface_t));
+    surface = _cairo_malloc (sizeof (cairo_pdf_surface_t));
     if (unlikely (surface == NULL)) {
 	/* destroy stream on behalf of caller */
 	status = _cairo_output_stream_destroy (output);
@@ -367,12 +407,19 @@
     _cairo_surface_init (&surface->base,
 			 &cairo_pdf_surface_backend,
 			 NULL, /* device */
-			 CAIRO_CONTENT_COLOR_ALPHA);
+			 CAIRO_CONTENT_COLOR_ALPHA,
+			 TRUE); /* is_vector */
 
     surface->output = output;
     surface->width = width;
     surface->height = height;
-    cairo_matrix_init (&surface->cairo_to_pdf, 1, 0, 0, -1, 0, height);
+    cairo_matrix_init (&surface->cairo_to_pdf, 1, 0, 0, 1, 0, 0);
+    surface->in_xobject = FALSE;
+    surface->surface_extents.x = 0;
+    surface->surface_extents.y = 0;
+    surface->surface_extents.width  = ceil (surface->width);
+    surface->surface_extents.height = ceil (surface->height);
+    surface->surface_bounded = TRUE;
 
     _cairo_array_init (&surface->objects, sizeof (cairo_pdf_object_t));
     _cairo_array_init (&surface->pages, sizeof (cairo_pdf_resource_t));
@@ -384,7 +431,9 @@
 
     _cairo_array_init (&surface->page_patterns, sizeof (cairo_pdf_pattern_t));
     _cairo_array_init (&surface->page_surfaces, sizeof (cairo_pdf_source_surface_t));
+    _cairo_array_init (&surface->doc_surfaces, sizeof (cairo_pdf_source_surface_t));
     _cairo_array_init (&surface->jbig2_global, sizeof (cairo_pdf_jbig2_global_t));
+    _cairo_array_init (&surface->page_heights, sizeof (double));
     surface->all_surfaces = _cairo_hash_table_create (_cairo_pdf_source_surface_equal);
     if (unlikely (surface->all_surfaces == NULL)) {
 	status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
@@ -408,6 +457,7 @@
         goto BAIL2;
     }
 
+    surface->struct_tree_root.id = 0;
     surface->pdf_version = CAIRO_PDF_VERSION_1_5;
     surface->compress_content = TRUE;
     surface->pdf_stream.active = FALSE;
@@ -437,6 +487,26 @@
 						    surface);
     _cairo_pdf_operators_enable_actual_text(&surface->pdf_operators, TRUE);
 
+    status = _cairo_pdf_interchange_init (surface);
+    if (unlikely (status))
+	goto BAIL2;
+
+    surface->page_parent_tree = -1;
+    _cairo_array_init (&surface->page_annots, sizeof (cairo_pdf_resource_t));
+    surface->tagged = FALSE;
+    surface->current_page_label = NULL;
+    _cairo_array_init (&surface->page_labels, sizeof (char *));
+    surface->outlines_dict_res.id = 0;
+    surface->names_dict_res.id = 0;
+    surface->docinfo_res.id = 0;
+    surface->page_labels_res.id = 0;
+    surface->thumbnail_width = 0;
+    surface->thumbnail_height = 0;
+    surface->thumbnail_image = NULL;
+
+    if (getenv ("CAIRO_DEBUG_PDF") != NULL)
+	surface->compress_content = FALSE;
+
     surface->paginated_surface =  _cairo_paginated_surface_create (
 	                                  &surface->base,
 					  CAIRO_CONTENT_COLOR_ALPHA,
@@ -705,6 +775,143 @@
 	status = _cairo_surface_set_error (surface, status);
 }
 
+/**
+ * CAIRO_PDF_OUTLINE_ROOT:
+ *
+ * The root outline item in cairo_pdf_surface_add_outline().
+ *
+ * Since: 1.16
+ **/
+
+/**
+ * cairo_pdf_surface_add_outline:
+ * @surface: a PDF #cairo_surface_t
+ * @parent_id: the id of the parent item or %CAIRO_PDF_OUTLINE_ROOT if this is a top level item.
+ * @utf8: the name of the outline
+ * @link_attribs: the link attributes specifying where this outline links to
+ * @flags: outline item flags
+ *
+ * Add an item to the document outline hierarchy with the name @utf8
+ * that links to the location specified by @link_attribs. Link
+ * attributes have the same keys and values as the [Link Tag][link],
+ * excluding the "rect" attribute. The item will be a child of the
+ * item with id @parent_id. Use %CAIRO_PDF_OUTLINE_ROOT as the parent
+ * id of top level items.
+ *
+ * Return value: the id for the added item.
+ *
+ * Since: 1.16
+ **/
+int
+cairo_pdf_surface_add_outline (cairo_surface_t	         *surface,
+			       int                        parent_id,
+			       const char                *utf8,
+			       const char                *link_attribs,
+			       cairo_pdf_outline_flags_t  flags)
+{
+    cairo_pdf_surface_t *pdf_surface = NULL; /* hide compiler warning */
+    cairo_status_t status;
+    int id = 0;
+
+    if (! _extract_pdf_surface (surface, &pdf_surface))
+	return 0;
+
+    status = _cairo_pdf_interchange_add_outline (pdf_surface,
+						 parent_id,
+						 utf8,
+						 link_attribs,
+						 flags,
+						 &id);
+    if (status)
+	status = _cairo_surface_set_error (surface, status);
+
+    return id;
+}
+
+/**
+ * cairo_pdf_surface_set_metadata:
+ * @surface: a PDF #cairo_surface_t
+ * @metadata: The metadata item to set.
+ * @utf8: metadata value
+ *
+ * Set document metadata. The %CAIRO_PDF_METADATA_CREATE_DATE and
+ * %CAIRO_PDF_METADATA_MOD_DATE values must be in ISO-8601 format:
+ * YYYY-MM-DDThh:mm:ss. An optional timezone of the form "[+/-]hh:mm"
+ * or "Z" for UTC time can be appended. All other metadata values can be any UTF-8
+ * string.
+ *
+ * For example:
+ * <informalexample><programlisting>
+ * cairo_pdf_surface_set_metadata (surface, CAIRO_PDF_METADATA_TITLE, "My Document");
+ * cairo_pdf_surface_set_metadata (surface, CAIRO_PDF_METADATA_CREATE_DATE, "2015-12-31T23:59+02:00");
+ * </programlisting></informalexample>
+ *
+ * Since: 1.16
+ **/
+void
+cairo_pdf_surface_set_metadata (cairo_surface_t      *surface,
+				cairo_pdf_metadata_t  metadata,
+                                const char           *utf8)
+{
+    cairo_pdf_surface_t *pdf_surface = NULL; /* hide compiler warning */
+    cairo_status_t status;
+
+    if (! _extract_pdf_surface (surface, &pdf_surface))
+	return;
+
+    status = _cairo_pdf_interchange_set_metadata (pdf_surface, metadata, utf8);
+    if (status)
+	status = _cairo_surface_set_error (surface, status);
+}
+
+/**
+ * cairo_pdf_surface_set_page_label:
+ * @surface: a PDF #cairo_surface_t
+ * @utf8: The page label.
+ *
+ * Set page label for the current page.
+ *
+ * Since: 1.16
+ **/
+void
+cairo_pdf_surface_set_page_label (cairo_surface_t *surface,
+                                  const char      *utf8)
+{
+    cairo_pdf_surface_t *pdf_surface = NULL; /* hide compiler warning */
+
+    if (! _extract_pdf_surface (surface, &pdf_surface))
+	return;
+
+    free (pdf_surface->current_page_label);
+    pdf_surface->current_page_label = utf8 ? strdup (utf8) : NULL;
+}
+
+/**
+ * cairo_pdf_surface_set_thumbnail_size:
+ * @surface: a PDF #cairo_surface_t
+ * @width: Thumbnail width.
+ * @height: Thumbnail height
+ *
+ * Set the thumbnail image size for the current and all subsequent
+ * pages. Setting a width or height of 0 disables thumbnails for the
+ * current and subsequent pages.
+ *
+ * Since: 1.16
+ **/
+void
+cairo_pdf_surface_set_thumbnail_size (cairo_surface_t *surface,
+				      int              width,
+				      int              height)
+{
+    cairo_pdf_surface_t *pdf_surface = NULL; /* hide compiler warning */
+
+    if (! _extract_pdf_surface (surface, &pdf_surface))
+	return;
+
+    pdf_surface->thumbnail_width = width;
+    pdf_surface->thumbnail_height = height;
+}
+
 static void
 _cairo_pdf_surface_clear (cairo_pdf_surface_t *surface)
 {
@@ -734,6 +941,10 @@
     }
     _cairo_array_truncate (&surface->smask_groups, 0);
     _cairo_array_truncate (&surface->knockout_group, 0);
+    _cairo_array_truncate (&surface->page_annots, 0);
+
+    cairo_surface_destroy (&surface->thumbnail_image->base);
+    surface->thumbnail_image = NULL;
 }
 
 static void
@@ -1080,7 +1291,6 @@
 	group->extents.width = surface->width;
 	group->extents.height = surface->height;
     }
-    group->extents = *extents;
 
     return group;
 }
@@ -1196,186 +1406,105 @@
 }
 
 static cairo_int_status_t
-_get_jbig2_image_info (cairo_surface_t		 *source,
-		       cairo_image_info_t	 *info,
-		       const unsigned char	**mime_data,
-		       unsigned long		 *mime_data_length)
+_get_source_surface_extents (cairo_surface_t         *source,
+			     cairo_rectangle_int_t   *extents,
+			     cairo_bool_t            *bounded,
+			     cairo_bool_t            *subsurface)
 {
-    cairo_surface_get_mime_data (source, CAIRO_MIME_TYPE_JBIG2,
-				 mime_data, mime_data_length);
-    if (*mime_data == NULL)
-	return CAIRO_INT_STATUS_UNSUPPORTED;
+    cairo_int_status_t status;
 
-    return _cairo_image_info_get_jbig2_info (info, *mime_data, *mime_data_length);
-}
+    *bounded = TRUE;
+    *subsurface = FALSE;
+    if (source->type == CAIRO_SURFACE_TYPE_RECORDING) {
+	cairo_surface_t *free_me = NULL;
 
-static cairo_int_status_t
-_get_jpx_image_info (cairo_surface_t		 *source,
-		     cairo_image_info_t		*info,
-		     const unsigned char	**mime_data,
-		     unsigned long		 *mime_data_length)
-{
-    cairo_surface_get_mime_data (source, CAIRO_MIME_TYPE_JP2,
-				 mime_data, mime_data_length);
-    if (*mime_data == NULL)
-	return CAIRO_INT_STATUS_UNSUPPORTED;
+	if (_cairo_surface_is_snapshot (source))
+	    free_me = source = _cairo_surface_snapshot_get_target (source);
 
-    return _cairo_image_info_get_jpx_info (info, *mime_data, *mime_data_length);
-}
-
-static cairo_int_status_t
-_get_jpeg_image_info (cairo_surface_t		 *source,
-		      cairo_image_info_t	 *info,
-		      const unsigned char	**mime_data,
-		      unsigned long		 *mime_data_length)
-{
-    cairo_surface_get_mime_data (source, CAIRO_MIME_TYPE_JPEG,
-				 mime_data, mime_data_length);
-    if (*mime_data == NULL)
-	return CAIRO_INT_STATUS_UNSUPPORTED;
-
-    return _cairo_image_info_get_jpeg_info (info, *mime_data, *mime_data_length);
-}
-
-static cairo_int_status_t
-_get_source_surface_size (cairo_surface_t         *source,
-			  int                     *width,
-			  int                     *height,
-			  cairo_rectangle_int_t   *extents)
-{
-    cairo_int_status_t status;
-    cairo_image_info_t info;
-    const unsigned char *mime_data;
-    unsigned long mime_data_length;
-
-    if (source->type == CAIRO_SURFACE_TYPE_RECORDING) {
 	if (source->backend->type == CAIRO_SURFACE_TYPE_SUBSURFACE) {
-	     cairo_surface_subsurface_t *sub = (cairo_surface_subsurface_t *) source;
+	    cairo_surface_subsurface_t *sub = (cairo_surface_subsurface_t *) source;
 
-	     *extents = sub->extents;
-	     *width  = extents->width;
-	     *height = extents->height;
+	    *extents = sub->extents;
+	    *subsurface = TRUE;
 	} else {
-	    cairo_surface_t *free_me = NULL;
-	    cairo_rectangle_int_t surf_extents;
 	    cairo_box_t box;
-	    cairo_bool_t bounded;
 
-	    if (_cairo_surface_is_snapshot (source))
-		free_me = source = _cairo_surface_snapshot_get_target (source);
-
-	    status = _cairo_recording_surface_get_ink_bbox ((cairo_recording_surface_t *)source,
-							    &box, NULL);
-	    if (unlikely (status)) {
-		cairo_surface_destroy (free_me);
-		return status;
+	    *bounded = _cairo_surface_get_extents (source, extents);
+	    if (! *bounded) {
+		status = _cairo_recording_surface_get_ink_bbox ((cairo_recording_surface_t *)source,
+								&box, NULL);
+		if (unlikely (status)) {
+		    cairo_surface_destroy (free_me);
+		    return status;
+		}
+		_cairo_box_round_to_rectangle (&box, extents);
 	    }
-
-	    bounded = _cairo_surface_get_extents (source, &surf_extents);
-	    cairo_surface_destroy (free_me);
-
-	    *width = surf_extents.width;
-	    *height = surf_extents.height;
-
-	    _cairo_box_round_to_rectangle (&box, extents);
 	}
-
-	return CAIRO_STATUS_SUCCESS;
+	cairo_surface_destroy (free_me);
+    } else {
+	*bounded =  _cairo_surface_get_extents (source, extents);
     }
 
-    extents->x = 0;
-    extents->y = 0;
-
-    status = _get_jbig2_image_info (source, &info, &mime_data, &mime_data_length);
-    if (status != CAIRO_INT_STATUS_UNSUPPORTED) {
-	*width = info.width;
-	*height = info.height;
-	extents->width = info.width;
-	extents->height = info.height;
-	return status;
-    }
-
-    status = _get_jpx_image_info (source, &info, &mime_data, &mime_data_length);
-    if (status != CAIRO_INT_STATUS_UNSUPPORTED) {
-	*width = info.width;
-	*height = info.height;
-	extents->width = info.width;
-	extents->height = info.height;
-	return status;
-    }
-
-    status = _get_jpeg_image_info (source, &info, &mime_data, &mime_data_length);
-    if (status != CAIRO_INT_STATUS_UNSUPPORTED) {
-	*width = info.width;
-	*height = info.height;
-	extents->width = info.width;
-	extents->height = info.height;
-	return status;
-    }
-
-    if (! _cairo_surface_get_extents (source, extents))
-	return CAIRO_INT_STATUS_UNSUPPORTED;
-
-    *width = extents->width;
-    *height = extents->height;
-
     return CAIRO_STATUS_SUCCESS;
 }
 
 /**
  * _cairo_pdf_surface_add_source_surface:
- * @surface: the pdf surface
- * @source_surface: A #cairo_surface_t to use as the source surface
- * @source_pattern: A #cairo_pattern_t of type SURFACE or RASTER_SOURCE to use as the source
- * @op: the operator used to composite this source
- * @filter: filter type of the source pattern
- * @stencil_mask: if true, the surface will be written to the PDF as an /ImageMask
- * @smask: if true, only the alpha channel will be written (images only)
- * @extents: extents of the operation that is using this source
- * @smask_res: if not NULL, the image written will specify this resource as the smask for the image (images only)
- * @surface_res: return PDF resource number of the surface
- * @width: returns width of surface
- * @height: returns height of surface
- * @x_offset: x offset of surface
- * @t_offset: y offset of surface
- * @source_extents: returns extents of source (either ink extents or extents needed to cover @extents)
+ * @surface: [in] the pdf surface
+ * @source_surface: [in] A #cairo_surface_t to use as the source surface
+ * @source_pattern: [in] A #cairo_pattern_t of type SURFACE or RASTER_SOURCE to use as the source
+ * @op: [in] the operator used to composite this source
+ * @filter: [in] filter type of the source pattern
+ * @stencil_mask: [in] if true, the surface will be written to the PDF as an /ImageMask
+ * @smask: [in] if true, only the alpha channel will be written (images only)
+ * @need_transp_group: [in] if true and an XObject is used, make it a Transparency group
+ * @extents: [in] extents of the operation that is using this source
+ * @smask_res: [in] if not NULL, the image written will specify this resource as the smask for
+ * the image (images only)
+ * @pdf_source: [out] return pdf_source_surface entry in hash table
+ * @x_offset: [out] if not NULL return x offset of surface
+ * @y_offset: [out] if not NULL return y offset of surface
+ * @source_extents: [out] if not NULL return operation extents in source space
  *
  * Add surface or raster_source pattern to list of surfaces to be
  * written to the PDF file when the current page is finished. Returns
- * a PDF resource to reference the image. A hash table of all images
- * in the PDF files (keyed by CAIRO_MIME_TYPE_UNIQUE_ID or surface
- * unique_id) to ensure surfaces with the same id are only written
- * once to the PDF file.
+ * a PDF resource to reference the surface. A hash table of all
+ * surfaces in the PDF file (keyed by CAIRO_MIME_TYPE_UNIQUE_ID or
+ * surface unique_id) is used to ensure surfaces with the same id are
+ * only written once to the PDF file.
  *
  * Only one of @source_pattern or @source_surface is to be
  * specified. Set the other to NULL.
  **/
 static cairo_int_status_t
-_cairo_pdf_surface_add_source_surface (cairo_pdf_surface_t	    *surface,
-				       cairo_surface_t	            *source_surface,
-				       const cairo_pattern_t	    *source_pattern,
-				       cairo_operator_t              op,
-				       cairo_filter_t		     filter,
-				       cairo_bool_t                  stencil_mask,
-				       cairo_bool_t                  smask,
-				       const cairo_rectangle_int_t  *extents,
-				       cairo_pdf_resource_t	    *smask_res,
-				       cairo_pdf_resource_t	    *surface_res,
-				       int                          *width,
-				       int                          *height,
-				       double                       *x_offset,
-				       double                       *y_offset,
-				       cairo_rectangle_int_t        *source_extents)
+_cairo_pdf_surface_add_source_surface (cairo_pdf_surface_t	         *surface,
+				       cairo_surface_t	                 *source_surface,
+				       const cairo_pattern_t	         *source_pattern,
+				       cairo_operator_t                   op,
+				       cairo_filter_t		          filter,
+				       cairo_bool_t                       stencil_mask,
+				       cairo_bool_t                       smask,
+				       cairo_bool_t                       need_transp_group,
+				       const cairo_rectangle_int_t       *extents,
+				       cairo_pdf_resource_t	         *smask_res,
+				       cairo_pdf_source_surface_entry_t **pdf_source,
+				       double                            *x_offset,
+				       double                            *y_offset,
+				       cairo_rectangle_int_t             *source_extents)
 {
     cairo_pdf_source_surface_t src_surface;
     cairo_pdf_source_surface_entry_t surface_key;
     cairo_pdf_source_surface_entry_t *surface_entry;
-    cairo_int_status_t status;
+    cairo_int_status_t status = CAIRO_STATUS_SUCCESS;
     cairo_bool_t interpolate;
     unsigned char *unique_id = NULL;
     unsigned long unique_id_length = 0;
     cairo_image_surface_t *image;
     void *image_extra;
+    cairo_box_t box;
+    cairo_rectangle_int_t op_extents;
+    double x, y;
+    cairo_bool_t subsurface;
 
     switch (filter) {
     default:
@@ -1391,8 +1520,8 @@
 	break;
     }
 
-    *x_offset = 0;
-    *y_offset = 0;
+    x = 0;
+    y = 0;
     if (source_pattern) {
 	if (source_pattern->type == CAIRO_PATTERN_TYPE_RASTER_SOURCE) {
 	    status = _cairo_pdf_surface_acquire_source_image_from_pattern (surface, source_pattern,
@@ -1400,13 +1529,28 @@
 	    if (unlikely (status))
 		return status;
 	    source_surface = &image->base;
-	    cairo_surface_get_device_offset (source_surface, x_offset, y_offset);
+	    cairo_surface_get_device_offset (source_surface, &x, &y);
 	} else {
 	    cairo_surface_pattern_t *surface_pattern = (cairo_surface_pattern_t *) source_pattern;
 	    source_surface = surface_pattern->surface;
 	}
     }
+    if (x_offset)
+	*x_offset = x;
+    if (y_offset)
+	*y_offset = y;
 
+    /* transform operation extents to pattern space */
+    op_extents = *extents;
+    if (source_pattern)
+    {
+	_cairo_box_from_rectangle (&box, extents);
+	_cairo_matrix_transform_bounding_box_fixed (&source_pattern->matrix, &box, NULL);
+	_cairo_box_round_to_rectangle (&box, &op_extents);
+    }
+    if (source_extents)
+	*source_extents = op_extents;
+
     surface_key.id  = source_surface->unique_id;
     surface_key.interpolate = interpolate;
     cairo_surface_get_mime_data (source_surface, CAIRO_MIME_TYPE_UNIQUE_ID,
@@ -1415,61 +1559,76 @@
     _cairo_pdf_source_surface_init_key (&surface_key);
     surface_entry = _cairo_hash_table_lookup (surface->all_surfaces, &surface_key.base);
     if (surface_entry) {
-	*surface_res = surface_entry->surface_res;
-	*width = surface_entry->width;
-	*height = surface_entry->height;
-	*source_extents = surface_entry->extents;
+	if (pdf_source)
+	    *pdf_source = surface_entry;
+
+	if (source_pattern && source_pattern->extend != CAIRO_EXTEND_NONE)
+	    _cairo_unbounded_rectangle_init (&op_extents);
+
+	_cairo_rectangle_intersect (&op_extents, &surface_entry->extents);
+	_cairo_rectangle_union (&surface_entry->required_extents, &op_extents);
 	status = CAIRO_STATUS_SUCCESS;
-    } else {
-	status = _get_source_surface_size (source_surface,
-					   width,
-					   height,
-					   source_extents);
-	if (unlikely(status))
-	    goto release_source;
+    }
 
-	if (surface_key.unique_id && surface_key.unique_id_length > 0) {
-	    unique_id = _cairo_malloc (surface_key.unique_id_length);
-	    if (unique_id == NULL) {
-		status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
-		goto release_source;
-	    }
+    if (status || surface_entry) {
+	if (source_pattern && source_pattern->type == CAIRO_PATTERN_TYPE_RASTER_SOURCE)
+	    _cairo_pdf_surface_release_source_image_from_pattern (surface, source_pattern, image, image_extra);
+	return status;
+    }
 
-	    unique_id_length = surface_key.unique_id_length;
+    if (surface_key.unique_id && surface_key.unique_id_length > 0) {
+	unique_id = _cairo_malloc (surface_key.unique_id_length);
+	if (unique_id == NULL) {
+	    status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
+	    goto fail1;
+	}
+
+	unique_id_length = surface_key.unique_id_length;
 	    memcpy (unique_id, surface_key.unique_id, unique_id_length);
-	} else {
-	    unique_id = NULL;
-	    unique_id_length = 0;
-	}
+    } else {
+	unique_id = NULL;
+	unique_id_length = 0;
     }
 
-release_source:
-    if (source_pattern && source_pattern->type == CAIRO_PATTERN_TYPE_RASTER_SOURCE)
-	_cairo_pdf_surface_release_source_image_from_pattern (surface, source_pattern, image, image_extra);
-
-    if (status || surface_entry)
-	return status;
-
-    surface_entry = malloc (sizeof (cairo_pdf_source_surface_entry_t));
+    surface_entry = _cairo_malloc (sizeof (cairo_pdf_source_surface_entry_t));
     if (surface_entry == NULL) {
 	status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
 	goto fail1;
     }
 
+    if (pdf_source)
+	*pdf_source = surface_entry;
     surface_entry->id = surface_key.id;
     surface_entry->operator = op;
     surface_entry->interpolate = interpolate;
     surface_entry->stencil_mask = stencil_mask;
     surface_entry->smask = smask;
+    surface_entry->need_transp_group = need_transp_group;
     surface_entry->unique_id_length = unique_id_length;
     surface_entry->unique_id = unique_id;
-    surface_entry->width = *width;
-    surface_entry->height = *height;
-    surface_entry->extents = *source_extents;
     if (smask_res)
 	surface_entry->smask_res = *smask_res;
     else
 	surface_entry->smask_res.id = 0;
+
+    status = _get_source_surface_extents (source_surface,
+					  &surface_entry->extents,
+					  &surface_entry->bounded,
+					  &subsurface);
+    if (unlikely (status))
+	goto fail2;
+
+    if (subsurface) {
+	*x_offset = -surface_entry->extents.x;
+	*y_offset = -surface_entry->extents.y;
+    }
+
+    if (source_pattern && source_pattern->extend != CAIRO_EXTEND_NONE)
+	_cairo_unbounded_rectangle_init (&op_extents);
+
+    _cairo_rectangle_intersect (&op_extents, &surface_entry->extents);
+    surface_entry->required_extents = op_extents;
+
     _cairo_pdf_source_surface_init_key (surface_entry);
 
     src_surface.hash_entry = surface_entry;
@@ -1492,18 +1651,30 @@
 	goto fail3;
     }
 
-    status = _cairo_array_append (&surface->page_surfaces, &src_surface);
+    /* Test if surface will be emitted as image or recording */
+    status = _cairo_pdf_surface_emit_surface (surface, &src_surface, TRUE, &surface_entry->emit_image);
     if (unlikely (status))
 	goto fail3;
 
+    if (surface_entry->bounded) {
+	status = _cairo_array_append (&surface->page_surfaces, &src_surface);
+	if (unlikely (status))
+	    goto fail3;
+    } else {
+	status = _cairo_array_append (&surface->doc_surfaces, &src_surface);
+	if (unlikely (status))
+	    goto fail3;
+    }
+
     status = _cairo_hash_table_insert (surface->all_surfaces,
 				       &surface_entry->base);
     if (unlikely(status))
 	goto fail3;
 
-    *surface_res = surface_entry->surface_res;
+    if (source_pattern && source_pattern->type == CAIRO_PATTERN_TYPE_RASTER_SOURCE)
+	_cairo_pdf_surface_release_source_image_from_pattern (surface, source_pattern, image, image_extra);
 
-    return status;
+    return CAIRO_STATUS_SUCCESS;
 
 fail3:
     if (source_pattern && source_pattern->type == CAIRO_PATTERN_TYPE_RASTER_SOURCE)
@@ -1515,8 +1686,12 @@
     free (surface_entry);
 
 fail1:
-    free (unique_id);
+    if (unique_id)
+	free (unique_id);
 
+    if (source_pattern && source_pattern->type == CAIRO_PATTERN_TYPE_RASTER_SOURCE)
+	_cairo_pdf_surface_release_source_image_from_pattern (surface, source_pattern, image, image_extra);
+
     return status;
 }
 
@@ -1584,6 +1759,10 @@
 
     *pattern_res = pdf_pattern.pattern_res;
     *gstate_res = pdf_pattern.gstate_res;
+    /* If the pattern requires a gstate it will be drawn from within
+     * an XObject. The initial space of each XObject has an inverted
+     * Y-axis. */
+    pdf_pattern.inverted_y_axis = pdf_pattern.gstate_res.id ? TRUE : surface->in_xobject;
 
     status = _cairo_array_append (&surface->page_patterns, &pdf_pattern);
     if (unlikely (status)) {
@@ -1594,16 +1773,15 @@
     return CAIRO_INT_STATUS_SUCCESS;
 }
 
-/* Get BBox in PDF coordinates from extents in cairo coordinates */
+/* Get BBox from extents */
 static void
-_get_bbox_from_extents (double                       surface_height,
-		       const cairo_rectangle_int_t *extents,
-		       cairo_box_double_t          *bbox)
+_get_bbox_from_extents (const cairo_rectangle_int_t  *extents,
+			cairo_box_double_t           *bbox)
 {
     bbox->p1.x = extents->x;
-    bbox->p1.y = surface_height - (extents->y + extents->height);
+    bbox->p1.y = extents->y;
     bbox->p2.x = extents->x + extents->width;
-    bbox->p2.y = surface_height - extents->y;
+    bbox->p2.y = extents->y + extents->height;
 }
 
 static cairo_int_status_t
@@ -1705,6 +1883,7 @@
         surface->output = output;
 	_cairo_pdf_operators_set_stream (&surface->pdf_operators, surface->output);
     }
+    _cairo_pdf_operators_reset (&surface->pdf_operators);
 
     return _cairo_output_stream_get_status (surface->output);
 }
@@ -1965,6 +2144,9 @@
 					    resource,
 					    surface->compress_content,
 					    NULL);
+	_cairo_output_stream_printf (surface->output,
+				     "1 0 0 -1 0 %f cm\n",
+				     surface->height);
     }
     if (unlikely (status))
 	return status;
@@ -1972,6 +2154,7 @@
     surface->content = surface->pdf_stream.self;
 
     _cairo_output_stream_printf (surface->output, "q\n");
+    _cairo_pdf_operators_reset (&surface->pdf_operators);
 
     return _cairo_output_stream_get_status (surface->output);
 }
@@ -2021,11 +2204,17 @@
 {
     cairo_pdf_surface_t *surface = abstract_surface;
     long offset;
-    cairo_pdf_resource_t info, catalog;
+    cairo_pdf_resource_t catalog;
     cairo_status_t status, status2;
     int size, i;
     cairo_pdf_jbig2_global_t *global;
+    char *label;
 
+    _cairo_pdf_surface_clear (surface);
+
+    /* Emit unbounded surfaces */
+    _cairo_pdf_surface_write_patterns_and_smask_groups (surface, TRUE);
+
     status = surface->base.status;
     if (status == CAIRO_STATUS_SUCCESS)
 	status = _cairo_pdf_surface_emit_font_subsets (surface);
@@ -2032,9 +2221,9 @@
 
     _cairo_pdf_surface_write_pages (surface);
 
-    info = _cairo_pdf_surface_write_info (surface);
-    if (info.id == 0 && status == CAIRO_STATUS_SUCCESS)
-	status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
+    status = _cairo_pdf_interchange_write_document_objects (surface);
+    if (unlikely (status))
+	return status;
 
     catalog = _cairo_pdf_surface_write_catalog (surface);
     if (catalog.id == 0 && status == CAIRO_STATUS_SUCCESS)
@@ -2050,7 +2239,7 @@
 				 ">>\n",
 				 surface->next_available_resource.id,
 				 catalog.id,
-				 info.id);
+				 surface->docinfo_res.id);
 
     _cairo_output_stream_printf (surface->output,
 				 "startxref\n"
@@ -2090,7 +2279,6 @@
     if (status == CAIRO_STATUS_SUCCESS)
 	status = status2;
 
-    _cairo_pdf_surface_clear (surface);
     _cairo_pdf_group_resources_fini (&surface->resources);
 
     _cairo_array_fini (&surface->objects);
@@ -2099,6 +2287,7 @@
     _cairo_array_fini (&surface->alpha_linear_functions);
     _cairo_array_fini (&surface->page_patterns);
     _cairo_array_fini (&surface->page_surfaces);
+    _cairo_array_fini (&surface->doc_surfaces);
     _cairo_hash_table_foreach (surface->all_surfaces,
 			       _cairo_pdf_source_surface_entry_pluck,
 			       surface->all_surfaces);
@@ -2106,6 +2295,7 @@
     _cairo_array_fini (&surface->smask_groups);
     _cairo_array_fini (&surface->fonts);
     _cairo_array_fini (&surface->knockout_group);
+    _cairo_array_fini (&surface->page_annots);
 
     if (surface->font_subsets) {
 	_cairo_scaled_font_subsets_destroy (surface->font_subsets);
@@ -2120,12 +2310,18 @@
 	    return _cairo_error (CAIRO_STATUS_JBIG2_GLOBAL_MISSING);
     }
     _cairo_array_fini (&surface->jbig2_global);
+    _cairo_array_fini (&surface->page_heights);
 
-    _cairo_array_truncate (&surface->page_surfaces, 0);
+    size = _cairo_array_num_elements (&surface->page_labels);
+    for (i = 0; i < size; i++) {
+	_cairo_array_copy_element (&surface->page_labels, i, &label);
+	free (label);
+    }
+    _cairo_array_fini (&surface->page_labels);
 
     _cairo_surface_clipper_reset (&surface->clipper);
 
-    return status;
+    return _cairo_pdf_interchange_fini (surface);
 }
 
 static cairo_int_status_t
@@ -2132,6 +2328,8 @@
 _cairo_pdf_surface_start_page (void *abstract_surface)
 {
     cairo_pdf_surface_t *surface = abstract_surface;
+    cairo_pdf_resource_t page;
+    cairo_int_status_t status;
 
     /* Document header */
     if (! surface->header_emitted) {
@@ -2155,7 +2353,16 @@
     }
 
     _cairo_pdf_group_resources_clear (&surface->resources);
+    surface->in_xobject = FALSE;
 
+    page = _cairo_pdf_surface_new_object (surface);
+    if (page.id == 0)
+	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
+
+    status = _cairo_array_append (&surface->pages, &page);
+    if (unlikely (status))
+	return status;
+
     return CAIRO_STATUS_SUCCESS;
 }
 
@@ -2168,6 +2375,7 @@
     cairo_box_double_t bbox;
 
     surface->has_fallback_images = has_fallbacks;
+    surface->in_xobject = has_fallbacks;
     bbox.p1.x = 0;
     bbox.p1.y = 0;
     bbox.p2.x = surface->width;
@@ -2185,15 +2393,41 @@
     return TRUE;
 }
 
+static cairo_bool_t
+_cairo_pdf_surface_requires_thumbnail_image (void *abstract_surface,
+					     int  *width,
+					     int  *height)
+{
+    cairo_pdf_surface_t *surface = abstract_surface;
+
+    if (surface->thumbnail_width > 0 && surface->thumbnail_height > 0) {
+	*width = surface->thumbnail_width;
+	*height = surface->thumbnail_height;
+	return TRUE;
+    }
+
+    return FALSE;
+}
+
 static cairo_int_status_t
+_cairo_pdf_surface_set_thumbnail_image (void                  *abstract_surface,
+					cairo_image_surface_t *image)
+{
+    cairo_pdf_surface_t *surface = abstract_surface;
+
+    surface->thumbnail_image = 	(cairo_image_surface_t *)cairo_surface_reference(&image->base);
+
+    return CAIRO_STATUS_SUCCESS;
+}
+
+static cairo_int_status_t
 _cairo_pdf_surface_add_padded_image_surface (cairo_pdf_surface_t          *surface,
 					     const cairo_pattern_t        *source,
 					     const cairo_rectangle_int_t  *extents,
-					     cairo_pdf_resource_t         *surface_res,
-					     int                          *width,
-					     int                          *height,
+					     cairo_pdf_source_surface_entry_t **pdf_source,
 					     double                       *x_offset,
-					     double                       *y_offset)
+					     double                       *y_offset,
+					     cairo_rectangle_int_t        *source_extents)
 {
     cairo_image_surface_t *image;
     cairo_surface_t *pad_image;
@@ -2200,7 +2434,6 @@
     void *image_extra;
     cairo_int_status_t status;
     int w, h;
-    cairo_rectangle_int_t extents2;
     cairo_box_t box;
     cairo_rectangle_int_t rect;
     cairo_surface_pattern_t pad_pattern;
@@ -2247,18 +2480,17 @@
     status = _cairo_pdf_surface_add_source_surface (surface,
 						    pad_image,
 						    NULL,
-						    FALSE,
+						    CAIRO_OPERATOR_OVER, /* not used for images */
 						    source->filter,
-						    FALSE,
-						    FALSE,
+						    FALSE, /* stencil mask */
+						    FALSE, /* smask */
+						    FALSE, /* need_transp_group */
 						    extents,
-						    NULL,
-						    surface_res,
-						    width,
-						    height,
+						    NULL, /* smask_res */
+						    pdf_source,
 						    x_offset,
 						    y_offset,
-						    &extents2);
+						    source_extents);
     if (unlikely (status))
         goto BAIL;
 
@@ -2642,7 +2874,7 @@
 	}
     }
 
-    global.id = malloc(global_id_length);
+    global.id = _cairo_malloc (global_id_length);
     if (unlikely (global.id == NULL)) {
 	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
     }
@@ -2668,7 +2900,8 @@
 static cairo_int_status_t
 _cairo_pdf_surface_emit_jbig2_image (cairo_pdf_surface_t              *surface,
 				     cairo_surface_t	              *source,
-				     cairo_pdf_source_surface_entry_t *surface_entry)
+				     cairo_pdf_source_surface_entry_t *surface_entry,
+				     cairo_bool_t                      test)
 {
     cairo_int_status_t status;
     const unsigned char *mime_data;
@@ -2691,6 +2924,10 @@
     if (status)
 	return status;
 
+    /* At this point we know emitting jbig2 will succeed. */
+    if (test)
+	return CAIRO_STATUS_SUCCESS;
+
     cairo_surface_get_mime_data (source, CAIRO_MIME_TYPE_JBIG2_GLOBAL_ID,
 				 &global_id, &global_id_length);
     if (global_id && global_id_length > 0) {
@@ -2776,7 +3013,8 @@
 static cairo_int_status_t
 _cairo_pdf_surface_emit_jpx_image (cairo_pdf_surface_t              *surface,
 				   cairo_surface_t	            *source,
-				   cairo_pdf_source_surface_entry_t *surface_entry)
+				   cairo_pdf_source_surface_entry_t *surface_entry,
+				   cairo_bool_t                      test)
 {
     cairo_int_status_t status;
     const unsigned char *mime_data;
@@ -2807,6 +3045,10 @@
     else
 	smask_buf[0] = 0;
 
+    /* At this point we know emitting jpx will succeed. */
+    if (test)
+	return CAIRO_STATUS_SUCCESS;
+
     if (surface_entry->stencil_mask) {
 	status = _cairo_pdf_surface_open_stream (surface,
 						 &surface_entry->surface_res,
@@ -2851,7 +3093,8 @@
 static cairo_int_status_t
 _cairo_pdf_surface_emit_jpeg_image (cairo_pdf_surface_t              *surface,
 				    cairo_surface_t	             *source,
-				    cairo_pdf_source_surface_entry_t *surface_entry)
+				    cairo_pdf_source_surface_entry_t *surface_entry,
+				    cairo_bool_t                      test)
 {
     cairo_int_status_t status;
     const unsigned char *mime_data;
@@ -2891,6 +3134,10 @@
 	    return CAIRO_INT_STATUS_UNSUPPORTED;
     }
 
+    /* At this point we know emitting jpeg will succeed. */
+    if (test)
+	return CAIRO_STATUS_SUCCESS;
+
     if (surface_entry->smask_res.id)
 	snprintf(smask_buf, sizeof(smask_buf), "   /SMask %d 0 R\n", surface_entry->smask_res.id);
     else
@@ -2942,46 +3189,114 @@
 }
 
 static cairo_int_status_t
-_cairo_pdf_surface_emit_image_surface (cairo_pdf_surface_t        *surface,
-				       cairo_pdf_source_surface_t *source)
+_cairo_pdf_surface_emit_ccitt_image (cairo_pdf_surface_t              *surface,
+				     cairo_surface_t	             *source,
+				     cairo_pdf_source_surface_entry_t *surface_entry,
+				     cairo_bool_t                      test)
 {
-    cairo_image_surface_t *image;
-    void *image_extra;
-    cairo_int_status_t status;
+    cairo_status_t status;
+    const unsigned char *ccitt_data;
+    unsigned long ccitt_data_len;
+    const unsigned char *ccitt_params_string;
+    unsigned long ccitt_params_string_len;
+    char *params, *p, *end;
+    cairo_ccitt_params_t ccitt_params;
+    char buf[300];
 
-    if (source->type == CAIRO_PATTERN_TYPE_SURFACE) {
-	status = _cairo_pdf_surface_emit_jbig2_image (surface, source->surface, source->hash_entry);
-	if (status != CAIRO_INT_STATUS_UNSUPPORTED)
-	    return status;
+    cairo_surface_get_mime_data (source, CAIRO_MIME_TYPE_CCITT_FAX,
+				 &ccitt_data, &ccitt_data_len);
+    if (unlikely (source->status))
+	return source->status;
+    if (ccitt_data == NULL)
+	return CAIRO_INT_STATUS_UNSUPPORTED;
 
-	status = _cairo_pdf_surface_emit_jpx_image (surface, source->surface, source->hash_entry);
-	if (status != CAIRO_INT_STATUS_UNSUPPORTED)
-	    return status;
+    cairo_surface_get_mime_data (source, CAIRO_MIME_TYPE_CCITT_FAX_PARAMS,
+				 &ccitt_params_string, &ccitt_params_string_len);
+    if (unlikely (source->status))
+	return source->status;
+    if (ccitt_params_string == NULL)
+	return CAIRO_INT_STATUS_UNSUPPORTED;
 
-	status = _cairo_pdf_surface_emit_jpeg_image (surface, source->surface, source->hash_entry);
-	if (status != CAIRO_INT_STATUS_UNSUPPORTED)
-	    return status;
+    /* ensure params_string is null terminated */
+    params = malloc (ccitt_params_string_len + 1);
+    memcpy (params, ccitt_params_string, ccitt_params_string_len);
+    params[ccitt_params_string_len] = 0;
+    status = _cairo_tag_parse_ccitt_params (params, &ccitt_params);
+    if (unlikely(status))
+	return source->status;
+
+    free (params);
+
+    /* At this point we know emitting jbig2 will succeed. */
+    if (test)
+	return CAIRO_STATUS_SUCCESS;
+
+    p = buf;
+    *p = 0;
+    end = buf + sizeof(buf) - 1;
+    p += snprintf (p, end - p, "/Columns %d /Rows %d /K %d",
+				 ccitt_params.columns,
+				 ccitt_params.rows,
+				 ccitt_params.k);
+    if (ccitt_params.end_of_line)
+	p += snprintf (p, end - p, " /EndOfLine true");
+
+    if (ccitt_params.encoded_byte_align)
+	p += snprintf (p, end - p, " /EncodedByteAlign true");
+
+    if (!ccitt_params.end_of_block)
+	p += snprintf (p, end - p, " /EndOfBlock false");
+
+    if (ccitt_params.black_is_1)
+	p += snprintf (p, end - p, " /BlackIs1 true");
+
+    if (ccitt_params.damaged_rows_before_error > 0) {
+	p += snprintf (p, end - p, " /DamagedRowsBeforeError %d",
+		       ccitt_params.damaged_rows_before_error);
     }
 
-    if (source->type == CAIRO_PATTERN_TYPE_SURFACE) {
-	status = _cairo_surface_acquire_source_image (source->surface, &image, &image_extra);
+    if (surface_entry->stencil_mask) {
+	status = _cairo_pdf_surface_open_stream (surface,
+						 &surface_entry->surface_res,
+						 FALSE,
+						 "   /Type /XObject\n"
+						 "   /Subtype /Image\n"
+						 "   /ImageMask true\n"
+						 "   /Width %d\n"
+						 "   /Height %d\n"
+						 "   /Interpolate %s\n"
+						 "   /BitsPerComponent 1\n"
+						 "   /Decode [1 0]\n"
+						 "   /Filter /CCITTFaxDecode\n"
+						 "   /DecodeParms << %s >> ",
+						 ccitt_params.columns,
+						 ccitt_params.rows,
+						 surface_entry->interpolate ? "true" : "false",
+						 buf);
     } else {
-	status = _cairo_pdf_surface_acquire_source_image_from_pattern (surface, source->raster_pattern,
-								       &image, &image_extra);
+	status = _cairo_pdf_surface_open_stream (surface,
+						 &surface_entry->surface_res,
+						 FALSE,
+						 "   /Type /XObject\n"
+						 "   /Subtype /Image\n"
+						 "   /Width %d\n"
+						 "   /Height %d\n"
+						 "   /ColorSpace /DeviceGray\n"
+						 "   /BitsPerComponent 1\n"
+						 "   /Interpolate %s\n"
+						 "   /Filter /CCITTFaxDecode\n"
+						 "   /DecodeParms << %s >> ",
+						 ccitt_params.columns,
+						 ccitt_params.rows,
+						 surface_entry->interpolate ? "true" : "false",
+						 buf);
     }
     if (unlikely (status))
 	return status;
 
-    status = _cairo_pdf_surface_emit_image (surface,
-					    image,
-					    source->hash_entry);
+    _cairo_output_stream_write (surface->output, ccitt_data, ccitt_data_len);
+    status = _cairo_pdf_surface_close_stream (surface);
 
-    if (source->type == CAIRO_PATTERN_TYPE_SURFACE)
-	_cairo_surface_release_source_image (source->surface, image, image_extra);
-    else
-	_cairo_pdf_surface_release_source_image_from_pattern (surface, source->raster_pattern,
-							      image, image_extra);
-
     return status;
 }
 
@@ -2989,9 +3304,11 @@
 _cairo_pdf_surface_emit_recording_surface (cairo_pdf_surface_t        *surface,
 					   cairo_pdf_source_surface_t *pdf_source)
 {
-    double old_width, old_height;
+    cairo_rectangle_int_t old_surface_extents;
+    cairo_bool_t old_surface_bounded;
     cairo_paginated_mode_t old_paginated_mode;
     cairo_surface_clipper_t old_clipper;
+    cairo_bool_t old_in_xobject;
     cairo_box_double_t bbox;
     cairo_int_status_t status;
     int alpha = 0;
@@ -2998,27 +3315,28 @@
     cairo_surface_t *free_me = NULL;
     cairo_surface_t *source;
     const cairo_rectangle_int_t *extents;
-    int width;
-    int height;
     cairo_bool_t is_subsurface;
     cairo_bool_t transparency_group;
     cairo_recording_surface_t *recording;
 
     assert (pdf_source->type == CAIRO_PATTERN_TYPE_SURFACE);
-    extents = &pdf_source->hash_entry->extents;
-    width = pdf_source->hash_entry->width;
-    height = pdf_source->hash_entry->height;
+
+    if (pdf_source->hash_entry->bounded) {
+	extents = &pdf_source->hash_entry->extents;
+    } else {
+	extents = &pdf_source->hash_entry->required_extents;
+    }
+
     is_subsurface = FALSE;
     source = pdf_source->surface;
-    if (_cairo_surface_is_snapshot (source)) {
+    if (_cairo_surface_is_snapshot (source))
 	free_me = source = _cairo_surface_snapshot_get_target (source);
-    } else if (source->backend->type == CAIRO_SURFACE_TYPE_SUBSURFACE) {
+
+    if (source->backend->type == CAIRO_SURFACE_TYPE_SUBSURFACE) {
 	cairo_surface_subsurface_t *sub = (cairo_surface_subsurface_t *) source;
 
 	source = sub->target;
 	extents = &sub->extents;
-	width = extents->width;
-	height = extents->height;
 	is_subsurface = TRUE;
     }
 
@@ -3025,14 +3343,19 @@
     assert (source->type == CAIRO_SURFACE_TYPE_RECORDING);
     recording = (cairo_recording_surface_t *) source;
 
-    old_width = surface->width;
-    old_height = surface->height;
+    old_in_xobject = surface->in_xobject;
+    old_surface_extents = surface->surface_extents;
+    old_surface_bounded = surface->surface_bounded;
     old_paginated_mode = surface->paginated_mode;
     old_clipper = surface->clipper;
+    surface->surface_extents = *extents;
     _cairo_surface_clipper_init (&surface->clipper,
 				 _cairo_pdf_surface_clipper_intersect_clip_path);
 
-    _cairo_pdf_surface_set_size_internal (surface, width, height);
+    _cairo_pdf_operators_reset (&surface->pdf_operators);
+    surface->in_xobject = TRUE;
+    surface->surface_extents = *extents;
+    surface->surface_bounded = TRUE;
 
     /* Patterns are emitted after fallback images. The paginated mode
      * needs to be set to _RENDER while the recording surface is replayed
@@ -3040,17 +3363,24 @@
      */
     surface->paginated_mode = CAIRO_PAGINATED_MODE_RENDER;
     _cairo_pdf_group_resources_clear (&surface->resources);
-    _get_bbox_from_extents (height, extents, &bbox);
+    _get_bbox_from_extents (extents, &bbox);
 
     /* We can optimize away the transparency group allowing the viewer
-     * to replay the group in place when all operators are OVER and the
-     * recording contains only opaque and/or clear alpha.
+     * to replay the group in place when:
+     *  - ca/CA when painting this groups is 1.0 (need_transp_group is FALSE),
+     *  - all operators are OVER, and
+     *  - the recording contains only opaque and/or clear alpha.
      */
-    transparency_group = !(pdf_source->hash_entry->operator == CAIRO_OPERATOR_OVER &&
+    transparency_group = pdf_source->hash_entry->need_transp_group ||
+	!(pdf_source->hash_entry->operator == CAIRO_OPERATOR_OVER &&
 			   _cairo_recording_surface_has_only_bilevel_alpha (recording) &&
 			   _cairo_recording_surface_has_only_op_over (recording));
-    status = _cairo_pdf_surface_open_content_stream (surface, &bbox, &pdf_source->hash_entry->surface_res,
-						     TRUE, transparency_group);
+
+    status = _cairo_pdf_surface_open_content_stream (surface,
+						     &bbox,
+						     &pdf_source->hash_entry->surface_res,
+						     TRUE,
+						     transparency_group);
     if (unlikely (status))
 	goto err;
 
@@ -3060,10 +3390,12 @@
 	    goto err;
 
 	_cairo_output_stream_printf (surface->output,
-				     "q /a%d gs 0 0 0 rg 0 0 %f %f re f Q\n",
+				     "q /a%d gs 0 0 0 rg %d %d %d %d re f Q\n",
 				     alpha,
-				     surface->width,
-				     surface->height);
+				     extents->x,
+				     extents->y,
+				     extents->width,
+				     extents->height);
     }
 
     status = _cairo_recording_surface_replay_region (source,
@@ -3078,10 +3410,11 @@
 
     _cairo_surface_clipper_reset (&surface->clipper);
     surface->clipper = old_clipper;
-    _cairo_pdf_surface_set_size_internal (surface,
-					  old_width,
-					  old_height);
+    _cairo_pdf_operators_reset (&surface->pdf_operators);
+    surface->in_xobject = old_in_xobject;
     surface->paginated_mode = old_paginated_mode;
+    surface->surface_extents = old_surface_extents;
+    surface->surface_bounded = old_surface_bounded;
 
 err:
     cairo_surface_destroy (free_me);
@@ -3088,15 +3421,107 @@
     return status;
 }
 
+/**
+ * _cairo_pdf_surface_emit_surface:
+ * @surface: [in] the pdf surface
+ * @source: [in] #cairo_pdf_source_surface_t containing the surface to write
+ * @test: [in] if true, test what type of surface will be emitted.
+ * @is_image: [out] if @test is true, returns TRUE if the surface will be emitted
+ *  as an Image XObject.
+ *
+ * If @test is FALSE, emit @src_surface as an XObject.
+ * If @test is TRUE, don't emit anything. Set @is_image based on the output that would be emitted.
+ **/
 static cairo_int_status_t
 _cairo_pdf_surface_emit_surface (cairo_pdf_surface_t        *surface,
-				 cairo_pdf_source_surface_t *src_surface)
+				 cairo_pdf_source_surface_t *source,
+				 cairo_bool_t                test,
+				 cairo_bool_t               *is_image)
 {
-    if (src_surface->type == CAIRO_PATTERN_TYPE_SURFACE &&
-	src_surface->surface->type == CAIRO_SURFACE_TYPE_RECORDING)
-	return _cairo_pdf_surface_emit_recording_surface (surface, src_surface);
+    cairo_image_surface_t *image;
+    void *image_extra;
+    cairo_int_status_t status;
 
-    return _cairo_pdf_surface_emit_image_surface (surface, src_surface);
+    /* Try all the supported mime types and recording type, falling through
+     * each option if unsupported */
+    if (source->type == CAIRO_PATTERN_TYPE_SURFACE) {
+	status = _cairo_pdf_surface_emit_jbig2_image (surface,
+						      source->surface,
+						      source->hash_entry,
+						      test);
+	if (status != CAIRO_INT_STATUS_UNSUPPORTED) {
+	    *is_image = TRUE;
+	    return status;
+	}
+
+	status = _cairo_pdf_surface_emit_jpx_image (surface,
+						    source->surface,
+						    source->hash_entry,
+						    test);
+	if (status != CAIRO_INT_STATUS_UNSUPPORTED) {
+	    *is_image = TRUE;
+	    return status;
+	}
+
+	status = _cairo_pdf_surface_emit_jpeg_image (surface,
+						     source->surface,
+						     source->hash_entry,
+						     test);
+	if (status != CAIRO_INT_STATUS_UNSUPPORTED) {
+	    *is_image = TRUE;
+	    return status;
+	}
+
+	status = _cairo_pdf_surface_emit_ccitt_image (surface,
+						      source->surface,
+						      source->hash_entry,
+						      test);
+	if (status != CAIRO_INT_STATUS_UNSUPPORTED) {
+	    *is_image = TRUE;
+	    return status;
+	}
+
+	if (source->surface->type == CAIRO_SURFACE_TYPE_RECORDING) {
+	    if (test) {
+		*is_image = FALSE;
+		return CAIRO_INT_STATUS_SUCCESS;
+	    } else {
+		return _cairo_pdf_surface_emit_recording_surface (surface, source);
+	    }
+	}
+    }
+
+    /* The only option left is to emit as an image surface */
+
+    if (source->type == CAIRO_PATTERN_TYPE_SURFACE) {
+	status = _cairo_surface_acquire_source_image (source->surface, &image, &image_extra);
+    } else {
+	status = _cairo_pdf_surface_acquire_source_image_from_pattern (surface,
+								       source->raster_pattern,
+								       &image,
+								       &image_extra);
+    }
+    if (unlikely (status))
+	return status;
+
+    if (test) {
+	*is_image = TRUE;
+    } else {
+	status = _cairo_pdf_surface_emit_image (surface,
+						image,
+						source->hash_entry);
+    }
+
+    if (source->type == CAIRO_PATTERN_TYPE_SURFACE) {
+	_cairo_surface_release_source_image (source->surface, image, image_extra);
+    } else {
+	_cairo_pdf_surface_release_source_image_from_pattern (surface,
+							      source->raster_pattern,
+							      image,
+							      image_extra);
+    }
+
+    return status;
 }
 
 static cairo_int_status_t
@@ -3105,31 +3530,28 @@
 {
     cairo_pattern_t *pattern = pdf_pattern->pattern;
     cairo_int_status_t status;
-    cairo_pdf_resource_t pattern_resource = {0};
     cairo_matrix_t cairo_p2d, pdf_p2d;
     cairo_extend_t extend = cairo_pattern_get_extend (pattern);
     double xstep, ystep;
     cairo_rectangle_int_t pattern_extents;
-    int pattern_width = 0; /* squelch bogus compiler warning */
-    int pattern_height = 0; /* squelch bogus compiler warning */
     double x_offset;
     double y_offset;
-    char draw_surface[200];
-    cairo_box_double_t     bbox;
+    char draw_surface[50];
+    char draw_surface2[200];
+    cairo_box_double_t bbox;
+    cairo_matrix_t mat;
+    cairo_pdf_source_surface_entry_t *pdf_source;
+    cairo_rectangle_int_t op_extents;
 
+    assert (pattern->type == CAIRO_PATTERN_TYPE_SURFACE);
     if (pattern->extend == CAIRO_EXTEND_PAD) {
 	status = _cairo_pdf_surface_add_padded_image_surface (surface,
 							      pattern,
 							      &pdf_pattern->extents,
-							      &pattern_resource,
-							      &pattern_width,
-							      &pattern_height,
+							      &pdf_source,
 							      &x_offset,
-							      &y_offset);
-	pattern_extents.x = 0;
-	pattern_extents.y = 0;
-	pattern_extents.width = pattern_width;
-	pattern_extents.height = pattern_height;
+							      &y_offset,
+							      &op_extents);
     } else {
 	status = _cairo_pdf_surface_add_source_surface (surface,
 							NULL,
@@ -3136,20 +3558,26 @@
 							pattern,
 							pdf_pattern->operator,
 							pattern->filter,
-							FALSE,
-							FALSE,
+							FALSE, /* stencil mask */
+							FALSE, /* smask */
+							FALSE, /* need_transp_group */
 							&pdf_pattern->extents,
-							NULL,
-							&pattern_resource,
-							&pattern_width,
-							&pattern_height,
+							NULL, /* smask_res */
+							&pdf_source,
 							&x_offset,
 							&y_offset,
-							&pattern_extents);
+							&op_extents);
     }
     if (unlikely (status))
 	return status;
 
+    pattern_extents = pdf_source->extents;
+    if (!pdf_source->bounded)
+    {
+	extend = CAIRO_EXTEND_NONE;
+	_cairo_rectangle_intersect (&pattern_extents, &op_extents);
+    }
+
     switch (extend) {
     case CAIRO_EXTEND_PAD:
     case CAIRO_EXTEND_NONE:
@@ -3167,7 +3595,8 @@
 	 * repeat visibly.
 	 */
 	double x1 = 0.0, y1 = 0.0;
-	double x2 = surface->width, y2 = surface->height;
+	double x2 = surface->surface_extents.width;
+	double y2 = surface->surface_extents.height;
 	_cairo_matrix_transform_bounding_box (&pattern->matrix,
 					      &x1, &y1, &x2, &y2,
 					      NULL);
@@ -3177,23 +3606,23 @@
 	 * required an answer that's large enough, we don't really
 	 * care if it's not as tight as possible.*/
 	xstep = ystep = ceil ((x2 - x1) + (y2 - y1) +
-			      pattern_width + pattern_height);
+			      pattern_extents.width + pattern_extents.height);
     }
     break;
     case CAIRO_EXTEND_REPEAT:
-	xstep = pattern_width;
-	ystep = pattern_height;
+	xstep = pattern_extents.width;
+	ystep = pattern_extents.height;
 	break;
+
     case CAIRO_EXTEND_REFLECT:
-	pattern_extents.x = 0;
-	pattern_extents.y = 0;
-	pattern_extents.width = pattern_width*2;
-	pattern_extents.height = pattern_height*2;
-	xstep = pattern_width*2;
-	ystep = pattern_height*2;
+	pattern_extents.width *= 2;
+	pattern_extents.height *= 2;
+	xstep = pattern_extents.width;
+	ystep = pattern_extents.height;
 	break;
-	/* All the rest (if any) should have been analyzed away, so this
-	 * case should be unreachable. */
+
+    /* All the rest (if any) should have been analyzed away, so this
+     * case should be unreachable. */
     default:
 	ASSERT_NOT_REACHED;
 	xstep = 0;
@@ -3232,12 +3661,19 @@
     /* cairo_pattern_set_matrix ensures the matrix is invertible */
     assert (status == CAIRO_INT_STATUS_SUCCESS);
 
-    cairo_matrix_multiply (&pdf_p2d, &cairo_p2d, &surface->cairo_to_pdf);
-    cairo_matrix_translate (&pdf_p2d, -x_offset, -y_offset);
-    cairo_matrix_translate (&pdf_p2d, 0.0, pattern_height);
-    cairo_matrix_scale (&pdf_p2d, 1.0, -1.0);
+    if (pdf_pattern->inverted_y_axis)
+	cairo_matrix_init (&mat, 1, 0, 0, 1, 0, 0);
+    else
+	cairo_matrix_init (&mat, 1, 0, 0, -1, 0, surface->height);
 
-    _get_bbox_from_extents (pattern_height, &pattern_extents, &bbox);
+    cairo_matrix_multiply (&pdf_p2d, &cairo_p2d, &mat);
+    cairo_matrix_translate (&pdf_p2d, x_offset, y_offset);
+    if (pdf_source->emit_image) {
+	cairo_matrix_translate (&pdf_p2d, 0.0, pdf_source->extents.height);
+	cairo_matrix_scale (&pdf_p2d, 1.0, -1.0);
+    }
+
+    _get_bbox_from_extents (&pattern_extents, &bbox);
     _cairo_pdf_surface_update_object (surface, pdf_pattern->pattern_res);
     status = _cairo_pdf_surface_open_stream (surface,
 				             &pdf_pattern->pattern_res,
@@ -3255,40 +3691,59 @@
 					     pdf_p2d.xx, pdf_p2d.yx,
 					     pdf_p2d.xy, pdf_p2d.yy,
 					     pdf_p2d.x0, pdf_p2d.y0,
-					     pattern_resource.id,
-					     pattern_resource.id);
+					     pdf_source->surface_res.id,
+					     pdf_source->surface_res.id);
     if (unlikely (status))
 	return status;
 
-    if (pattern->type == CAIRO_PATTERN_TYPE_SURFACE &&
-	((cairo_surface_pattern_t *) pattern)->surface->type == CAIRO_SURFACE_TYPE_RECORDING) {
+    if (pdf_source->emit_image) {
 	snprintf(draw_surface,
 		 sizeof (draw_surface),
-		 "/x%d Do\n",
-		 pattern_resource.id);
+		 "q %d 0 0 %d 0 0 cm /x%d Do Q",
+		 pdf_source->extents.width,
+		 pdf_source->extents.height,
+		 pdf_source->surface_res.id);
     } else {
 	snprintf(draw_surface,
 		 sizeof (draw_surface),
-		 "q %d 0 0 %d 0 0 cm /x%d Do Q",
-		 pattern_width,
-		 pattern_height,
-		 pattern_resource.id);
+		 "/x%d Do",
+		 pdf_source->surface_res.id);
     }
 
     if (extend == CAIRO_EXTEND_REFLECT) {
-	_cairo_output_stream_printf (surface->output,
-				     "q 0 0 %d %d re W n %s Q\n"
-				     "q -1 0 0 1 %d 0 cm 0 0 %d %d re W n %s Q\n"
-				     "q 1 0 0 -1 0 %d cm 0 0 %d %d re W n %s Q\n"
-				     "q -1 0 0 -1 %d %d cm 0 0 %d %d re W n %s Q\n",
-				     pattern_width, pattern_height,
-				     draw_surface,
-				     pattern_width*2, pattern_width, pattern_height,
-				     draw_surface,
-				     pattern_height*2, pattern_width, pattern_height,
-				     draw_surface,
-				     pattern_width*2, pattern_height*2, pattern_width, pattern_height,
-				     draw_surface);
+	cairo_rectangle_int_t p_extents = pdf_source->extents;
+	snprintf(draw_surface2,
+		 sizeof (draw_surface2),
+		 "%d %d %d %d re W n %s",
+		 p_extents.x, p_extents.y,
+		 p_extents.width, p_extents.height,
+		 draw_surface);
+
+	_cairo_output_stream_printf (surface->output, "q %s Q\n", draw_surface2);
+
+	cairo_matrix_init_translate (&mat, p_extents.x, p_extents.y);
+	cairo_matrix_scale (&mat, -1, 1);
+	cairo_matrix_translate (&mat, -2*p_extents.width, 0);
+	cairo_matrix_translate (&mat, -p_extents.x, -p_extents.y);
+	_cairo_output_stream_printf (surface->output, "q ");
+	_cairo_output_stream_print_matrix (surface->output, &mat);
+	_cairo_output_stream_printf (surface->output, " cm %s Q\n", draw_surface2);
+
+	cairo_matrix_init_translate (&mat, p_extents.x, p_extents.y);
+	cairo_matrix_scale (&mat, 1, -1);
+	cairo_matrix_translate (&mat, 0, -2*p_extents.height);
+	cairo_matrix_translate (&mat, -p_extents.x, -p_extents.y);
+	_cairo_output_stream_printf (surface->output, "q ");
+	_cairo_output_stream_print_matrix (surface->output, &mat);
+	_cairo_output_stream_printf (surface->output, " cm %s Q\n", draw_surface2);
+
+	cairo_matrix_init_translate (&mat, p_extents.x, p_extents.y);
+	cairo_matrix_scale (&mat, -1, -1);
+	cairo_matrix_translate (&mat, -2*p_extents.width, -2*p_extents.height);
+	cairo_matrix_translate (&mat, -p_extents.x, -p_extents.y);
+	_cairo_output_stream_printf (surface->output, "q ");
+	_cairo_output_stream_print_matrix (surface->output, &mat);
+	_cairo_output_stream_printf (surface->output, " cm %s Q\n", draw_surface2);
     } else {
 	_cairo_output_stream_printf (surface->output,
 				     " %s \n",
@@ -3736,7 +4191,7 @@
 
 	/* When emitting a shading operator we are in cairo pattern
 	 * coordinates. _cairo_pdf_surface_paint_gradient has set the
-	 * ctm to the pattern matrix (including the convertion from
+	 * ctm to the pattern matrix (including the conversion from
 	 * pdf to cairo coordinates) */
 	_cairo_box_from_rectangle (&box, &pdf_pattern->extents);
 	_cairo_box_to_doubles (&box, &x1, &y1, &x2, &y2);
@@ -3748,7 +4203,7 @@
 	 * coordinates. The color and alpha shading patterns painted
 	 * in the XObject below contain the cairo pattern to pdf page
 	 * matrix in the /Matrix entry of the pattern. */
-	_get_bbox_from_extents (pdf_pattern->height, &pdf_pattern->extents, &box);
+	_get_bbox_from_extents (&pdf_pattern->extents, &box);
 	x1 = box.p1.x;
 	y1 = box.p1.y;
 	x2 = box.p2.x;
@@ -3913,6 +4368,7 @@
     cairo_circle_double_t start, end;
     double domain[2];
     cairo_int_status_t status;
+    cairo_matrix_t mat;
 
     assert (pattern->n_stops != 0);
 
@@ -3927,8 +4383,14 @@
     status = cairo_matrix_invert (&pat_to_pdf);
     /* cairo_pattern_set_matrix ensures the matrix is invertible */
     assert (status == CAIRO_INT_STATUS_SUCCESS);
-    cairo_matrix_multiply (&pat_to_pdf, &pat_to_pdf, &surface->cairo_to_pdf);
 
+    if (pdf_pattern->inverted_y_axis)
+       cairo_matrix_init (&mat, 1, 0, 0, 1, 0, 0);
+    else
+       cairo_matrix_init (&mat, 1, 0, 0, -1, 0, surface->height);
+
+    cairo_matrix_multiply (&pat_to_pdf, &pat_to_pdf, &mat);
+
     if (pattern->base.extend == CAIRO_EXTEND_REPEAT ||
 	pattern->base.extend == CAIRO_EXTEND_REFLECT)
     {
@@ -4059,6 +4521,7 @@
     cairo_pdf_shading_t shading;
     int i;
     cairo_pdf_resource_t res;
+    cairo_matrix_t mat;
 
     pat_to_pdf = pattern->matrix;
     status = cairo_matrix_invert (&pat_to_pdf);
@@ -4065,8 +4528,13 @@
     /* cairo_pattern_set_matrix ensures the matrix is invertible */
     assert (status == CAIRO_INT_STATUS_SUCCESS);
 
-    cairo_matrix_multiply (&pat_to_pdf, &pat_to_pdf, &surface->cairo_to_pdf);
+    if (pdf_pattern->inverted_y_axis)
+	cairo_matrix_init (&mat, 1, 0, 0, 1, 0, 0);
+    else
+	cairo_matrix_init (&mat, 1, 0, 0, -1, 0, surface->height);
 
+    cairo_matrix_multiply (&pat_to_pdf, &pat_to_pdf, &mat);
+
     status = _cairo_pdf_shading_init_color (&shading, (cairo_mesh_pattern_t *) pattern);
     if (unlikely (status))
 	return status;
@@ -4197,15 +4665,8 @@
 static cairo_int_status_t
 _cairo_pdf_surface_emit_pattern (cairo_pdf_surface_t *surface, cairo_pdf_pattern_t *pdf_pattern)
 {
-    double old_width, old_height;
     cairo_int_status_t status;
 
-    old_width = surface->width;
-    old_height = surface->height;
-    _cairo_pdf_surface_set_size_internal (surface,
-					  pdf_pattern->width,
-					  pdf_pattern->height);
-
     switch (pdf_pattern->pattern->type) {
     case CAIRO_PATTERN_TYPE_SOLID:
 	ASSERT_NOT_REACHED;
@@ -4232,10 +4693,6 @@
 	break;
     }
 
-    _cairo_pdf_surface_set_size_internal (surface,
-					  old_width,
-					  old_height);
-
     return status;
 }
 
@@ -4244,17 +4701,16 @@
 					  cairo_operator_t              op,
 					  const cairo_pattern_t        *source,
 					  const cairo_rectangle_int_t  *extents,
+					  double                        alpha,
 					  cairo_pdf_resource_t	       *smask_res,
 					  cairo_bool_t                  stencil_mask)
 {
-    cairo_pdf_resource_t surface_res;
-    int width, height;
     cairo_matrix_t cairo_p2d, pdf_p2d;
     cairo_int_status_t status;
-    int alpha;
-    cairo_rectangle_int_t extents2;
+    int alpha_id;
     double x_offset;
     double y_offset;
+    cairo_pdf_source_surface_entry_t *pdf_source;
 
     if (source->extend == CAIRO_EXTEND_PAD &&
 	!(source->type == CAIRO_PATTERN_TYPE_SURFACE &&
@@ -4263,11 +4719,10 @@
 	status = _cairo_pdf_surface_add_padded_image_surface (surface,
 							      source,
 							      extents,
-							      &surface_res,
-							      &width,
-							      &height,
+							      &pdf_source,
 							      &x_offset,
-							      &y_offset);
+							      &y_offset,
+							      NULL);
     } else {
 	status = _cairo_pdf_surface_add_source_surface (surface,
 							NULL,
@@ -4275,15 +4730,14 @@
 							op,
 							source->filter,
 							stencil_mask,
-							FALSE,
+							FALSE, /* smask */
+							alpha != 1.0, /* need_transp_group */
 							extents,
 							smask_res,
-							&surface_res,
-							&width,
-							&height,
+							&pdf_source,
 							&x_offset,
 							&y_offset,
-							&extents2);
+							NULL);
     }
     if (unlikely (status))
 	return status;
@@ -4296,11 +4750,20 @@
     pdf_p2d = surface->cairo_to_pdf;
     cairo_matrix_multiply (&pdf_p2d, &cairo_p2d, &pdf_p2d);
     cairo_matrix_translate (&pdf_p2d, x_offset, y_offset);
-    cairo_matrix_translate (&pdf_p2d, 0.0, height);
-    cairo_matrix_scale (&pdf_p2d, 1.0, -1.0);
-    if (!(source->type == CAIRO_PATTERN_TYPE_SURFACE &&
-	  ((cairo_surface_pattern_t *)source)->surface->type == CAIRO_SURFACE_TYPE_RECORDING))
-    {
+    if (pdf_source->emit_image) {
+	int width, height;
+
+	if (pdf_source->bounded) {
+	    width = pdf_source->extents.width;
+	    height = pdf_source->extents.height;
+	} else {
+	    /* We can't scale an image to an unbounded surface size so just set the size to 1 */
+	    width = 1;
+	    height = 1;
+	}
+
+	cairo_matrix_translate (&pdf_p2d, 0.0, height);
+	cairo_matrix_scale (&pdf_p2d, 1.0, -1.0);
 	cairo_matrix_scale (&pdf_p2d, width, height);
     }
 
@@ -4313,7 +4776,7 @@
 	_cairo_output_stream_printf (surface->output, " cm\n");
     }
 
-    status = _cairo_pdf_surface_add_alpha (surface, 1.0, &alpha);
+    status = _cairo_pdf_surface_add_alpha (surface, alpha, &alpha_id);
     if (unlikely (status))
 	return status;
 
@@ -4320,15 +4783,15 @@
     if (stencil_mask) {
 	_cairo_output_stream_printf (surface->output,
 				     "/x%d Do\n",
-				     surface_res.id);
+				     pdf_source->surface_res.id);
     } else {
 	_cairo_output_stream_printf (surface->output,
 				     "/a%d gs /x%d Do\n",
-				     alpha,
-				     surface_res.id);
+				     alpha_id,
+				     pdf_source->surface_res.id);
     }
 
-    return _cairo_pdf_surface_add_xobject (surface, surface_res);
+    return _cairo_pdf_surface_add_xobject (surface, pdf_source->surface_res);
 }
 
 static cairo_int_status_t
@@ -4335,12 +4798,13 @@
 _cairo_pdf_surface_paint_gradient (cairo_pdf_surface_t         *surface,
 				   cairo_operator_t             op,
 				   const cairo_pattern_t       *source,
-				   const cairo_rectangle_int_t *extents)
+				   const cairo_rectangle_int_t *extents,
+				   double                       alpha)
 {
     cairo_pdf_resource_t shading_res, gstate_res;
     cairo_matrix_t pat_to_pdf;
     cairo_int_status_t status;
-    int alpha;
+    int alpha_id;
 
     status = _cairo_pdf_surface_add_pdf_shading (surface, source,
 						 op, extents,
@@ -4379,13 +4843,13 @@
 				     gstate_res.id,
 				     shading_res.id);
     } else {
-	status = _cairo_pdf_surface_add_alpha (surface, 1.0, &alpha);
+	status = _cairo_pdf_surface_add_alpha (surface, alpha, &alpha_id);
 	if (unlikely (status))
 	    return status;
 
 	_cairo_output_stream_printf (surface->output,
 				     "/a%d gs /sh%d sh\n",
-				     alpha,
+				     alpha_id,
 				     shading_res.id);
     }
 
@@ -4397,6 +4861,7 @@
 				  cairo_operator_t              op,
 				  const cairo_pattern_t        *source,
 				  const cairo_rectangle_int_t  *extents,
+				  double                        alpha,
 				  cairo_bool_t                  mask)
 {
     switch (source->type) {
@@ -4406,6 +4871,7 @@
 							 op,
 							 source,
 							 extents,
+							 alpha,
 							 NULL,
 							 mask);
     case CAIRO_PATTERN_TYPE_LINEAR:
@@ -4414,7 +4880,8 @@
 	return _cairo_pdf_surface_paint_gradient (surface,
 						  op,
 						  source,
-						  extents);
+						  extents,
+						  alpha);
 
     case CAIRO_PATTERN_TYPE_SOLID:
     default:
@@ -4593,6 +5060,20 @@
     cairo_pdf_surface_t *surface = abstract_surface;
     cairo_int_status_t status;
 
+    status = _cairo_array_append (&surface->page_heights, &surface->height);
+    if (unlikely (status))
+	return status;
+
+    status = _cairo_array_append (&surface->page_labels, &surface->current_page_label);
+    if (unlikely (status))
+	return status;
+
+    surface->current_page_label = NULL;
+
+    status = _cairo_pdf_interchange_end_page_content (surface);
+    if (unlikely (status))
+	return status;
+
     status = _cairo_pdf_surface_close_content_stream (surface);
     if (unlikely (status))
 	return status;
@@ -4614,17 +5095,10 @@
 {
     cairo_pdf_surface_t *surface = abstract_surface;
 
-    rectangle->x = 0;
-    rectangle->y = 0;
+    if (surface->surface_bounded)
+	*rectangle = surface->surface_extents;
 
-    /* XXX: The conversion to integers here is pretty bogus, (not to
-     * mention the arbitrary limitation of width to a short(!). We
-     * may need to come up with a better interface for get_size.
-     */
-    rectangle->width  = ceil (surface->width);
-    rectangle->height = ceil (surface->height);
-
-    return TRUE;
+    return surface->surface_bounded;
 }
 
 static void
@@ -4639,28 +5113,6 @@
     _cairo_font_options_set_round_glyph_positions (options, CAIRO_ROUND_GLYPH_POS_OFF);
 }
 
-static cairo_pdf_resource_t
-_cairo_pdf_surface_write_info (cairo_pdf_surface_t *surface)
-{
-    cairo_pdf_resource_t info;
-
-    info = _cairo_pdf_surface_new_object (surface);
-    if (info.id == 0)
-	return info;
-
-    _cairo_output_stream_printf (surface->output,
-				 "%d 0 obj\n"
-				 "<< /Creator (cairo %s (http://cairographics.org))\n"
-				 "   /Producer (cairo %s (http://cairographics.org))\n"
-				 ">>\n"
-				 "endobj\n",
-				 info.id,
-                                 cairo_version_string (),
-                                 cairo_version_string ());
-
-    return info;
-}
-
 static void
 _cairo_pdf_surface_write_pages (cairo_pdf_surface_t *surface)
 {
@@ -4691,8 +5143,8 @@
 				 "endobj\n");
 }
 
-static cairo_int_status_t
-_utf8_to_pdf_string (const char *utf8, char **str_out)
+cairo_int_status_t
+_cairo_utf8_to_pdf_string (const char *utf8, char **str_out)
 {
     int i;
     int len;
@@ -4711,7 +5163,7 @@
     }
 
     if (ascii) {
-	str = malloc (len + 3);
+	str = _cairo_malloc (len + 3);
 	if (str == NULL)
 	    return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
@@ -4728,7 +5180,7 @@
 	if (unlikely (status))
 	    return status;
 
-	str = malloc (utf16_len*4 + 7);
+	str = _cairo_malloc (utf16_len*4 + 7);
 	if (str == NULL) {
 	    free (utf16);
 	    return _cairo_error (CAIRO_STATUS_NO_MEMORY);
@@ -5037,7 +5489,7 @@
     if (subset->family_name_utf8) {
 	char *pdf_str;
 
-	status = _utf8_to_pdf_string (subset->family_name_utf8, &pdf_str);
+	status = _cairo_utf8_to_pdf_string (subset->family_name_utf8, &pdf_str);
 	if (likely (status == CAIRO_INT_STATUS_SUCCESS)) {
 	    _cairo_output_stream_printf (surface->output,
 					 "   /FontFamily %s\n",
@@ -5483,7 +5935,7 @@
     if (subset.family_name_utf8) {
 	char *pdf_str;
 
-	status = _utf8_to_pdf_string (subset.family_name_utf8, &pdf_str);
+	status = _cairo_utf8_to_pdf_string (subset.family_name_utf8, &pdf_str);
 	if (likely (status == CAIRO_INT_STATUS_SUCCESS)) {
 	    _cairo_output_stream_printf (surface->output,
 					 "   /FontFamily %s\n",
@@ -5855,7 +6307,7 @@
 				 "<< /Type /Font\n"
 				 "   /Subtype /Type3\n"
 				 "   /FontBBox [%f %f %f %f]\n"
-				 "   /FontMatrix [ 1 0 0 1 0 0 ]\n"
+				 "   /FontMatrix [ 1 0 0 -1 0 0 ]\n"
 				 "   /Encoding %d 0 R\n"
 				 "   /CharProcs %d 0 R\n"
 				 "   /FirstChar 0\n"
@@ -5862,9 +6314,9 @@
 				 "   /LastChar %d\n",
 				 subset_resource.id,
 				 _cairo_fixed_to_double (font_bbox.p1.x),
-				 - _cairo_fixed_to_double (font_bbox.p2.y),
+				 _cairo_fixed_to_double (font_bbox.p1.y),
 				 _cairo_fixed_to_double (font_bbox.p2.x),
-				 - _cairo_fixed_to_double (font_bbox.p1.y),
+				 _cairo_fixed_to_double (font_bbox.p2.y),
 				 encoding.id,
 				 char_procs.id,
 				 font_subset->num_glyphs - 1);
@@ -5988,12 +6440,42 @@
     _cairo_output_stream_printf (surface->output,
 				 "%d 0 obj\n"
 				 "<< /Type /Catalog\n"
-				 "   /Pages %d 0 R\n"
-				 ">>\n"
-				 "endobj\n",
+				 "   /Pages %d 0 R\n",
 				 catalog.id,
 				 surface->pages_resource.id);
 
+    if (surface->struct_tree_root.id != 0) {
+	_cairo_output_stream_printf (surface->output,
+				     "   /StructTreeRoot %d 0 R\n",
+				     surface->struct_tree_root.id);
+	if (surface->tagged) {
+	    _cairo_output_stream_printf (surface->output,
+					 "   /MarkInfo << /Marked true >>\n");
+	}
+    }
+
+    if (surface->outlines_dict_res.id != 0) {
+	_cairo_output_stream_printf (surface->output,
+				     "   /Outlines %d 0 R\n",
+				     surface->outlines_dict_res.id);
+    }
+
+    if (surface->page_labels_res.id != 0) {
+	_cairo_output_stream_printf (surface->output,
+				     "   /PageLabels %d 0 R\n",
+				     surface->page_labels_res.id);
+    }
+
+    if (surface->names_dict_res.id != 0) {
+	_cairo_output_stream_printf (surface->output,
+				     "   /Names %d 0 R\n",
+				     surface->names_dict_res.id);
+    }
+
+    _cairo_output_stream_printf (surface->output,
+				 ">>\n"
+				 "endobj\n");
+
     return catalog;
 }
 
@@ -6037,7 +6519,7 @@
     cairo_box_double_t bbox;
 
     /* Create mask group */
-    _get_bbox_from_extents (group->height, &group->extents, &bbox);
+    _get_bbox_from_extents (&group->extents, &bbox);
     status = _cairo_pdf_surface_open_group (surface, &bbox, NULL);
     if (unlikely (status))
 	return status;
@@ -6048,7 +6530,8 @@
 						   CAIRO_OPERATOR_OVER,
 						   group->mask,
 						   &group->extents,
-						   FALSE);
+						   1.0, /* alpha */
+						   FALSE); /* mask */
 	if (unlikely (status))
 	    return status;
 
@@ -6124,7 +6607,8 @@
 						   CAIRO_OPERATOR_OVER,
 						   group->source,
 						   &group->extents,
-						   FALSE);
+						   1.0, /* alpha */
+						   FALSE); /* mask */
 	if (unlikely (status))
 	    return status;
 
@@ -6224,14 +6708,20 @@
 				      cairo_pdf_smask_group_t *group)
 {
     double old_width, old_height;
+    cairo_bool_t old_in_xobject;
     cairo_int_status_t status;
     cairo_box_double_t bbox;
+    cairo_rectangle_int_t old_surface_extents;
 
     old_width = surface->width;
     old_height = surface->height;
+    old_surface_extents = surface->surface_extents;
+    old_in_xobject = surface->in_xobject;
+    surface->in_xobject = TRUE;
     _cairo_pdf_surface_set_size_internal (surface,
 					  group->width,
 					  group->height);
+    _cairo_pdf_operators_reset (&surface->pdf_operators);
     /* _mask is a special case that requires two groups - source
      * and mask as well as a smask and gstate dictionary */
     if (group->operation == PDF_MASK) {
@@ -6239,7 +6729,7 @@
 	goto RESTORE_SIZE;
     }
 
-    _get_bbox_from_extents (group->height, &group->extents, &bbox);
+    _get_bbox_from_extents (&group->extents, &bbox);
     status = _cairo_pdf_surface_open_group (surface, &bbox, &group->group_res);
     if (unlikely (status))
 	return status;
@@ -6291,21 +6781,26 @@
     status = _cairo_pdf_surface_close_group (surface, NULL);
 
 RESTORE_SIZE:
+    surface->in_xobject = old_in_xobject;
     _cairo_pdf_surface_set_size_internal (surface,
 					  old_width,
 					  old_height);
+    surface->surface_extents = old_surface_extents;
+    _cairo_pdf_operators_reset (&surface->pdf_operators);
 
     return status;
 }
 
 static cairo_int_status_t
-_cairo_pdf_surface_write_patterns_and_smask_groups (cairo_pdf_surface_t *surface)
+_cairo_pdf_surface_write_patterns_and_smask_groups (cairo_pdf_surface_t *surface,
+						    cairo_bool_t         finish)
 {
     cairo_pdf_pattern_t pattern;
     cairo_pdf_smask_group_t *group;
     cairo_pdf_source_surface_t src_surface;
-    unsigned int pattern_index, group_index, surface_index;
+    unsigned int pattern_index, group_index, surface_index, doc_surface_index;
     cairo_int_status_t status;
+    cairo_bool_t is_image;
 
     /* Writing out PDF_MASK groups will cause additional smask groups
      * to be appended to surface->smask_groups. Additional patterns
@@ -6317,9 +6812,11 @@
     pattern_index = 0;
     group_index = 0;
     surface_index = 0;
+    doc_surface_index = 0;
     while ((pattern_index < _cairo_array_num_elements (&surface->page_patterns)) ||
 	   (group_index < _cairo_array_num_elements (&surface->smask_groups)) ||
-	   (surface_index < _cairo_array_num_elements (&surface->page_surfaces)))
+	   (surface_index < _cairo_array_num_elements (&surface->page_surfaces)) ||
+	   (finish && (doc_surface_index < _cairo_array_num_elements (&surface->doc_surfaces))))
     {
 	for (; group_index < _cairo_array_num_elements (&surface->smask_groups); group_index++) {
 	    _cairo_array_copy_element (&surface->smask_groups, group_index, &group);
@@ -6337,10 +6834,19 @@
 
 	for (; surface_index < _cairo_array_num_elements (&surface->page_surfaces); surface_index++) {
 	    _cairo_array_copy_element (&surface->page_surfaces, surface_index, &src_surface);
-	    status = _cairo_pdf_surface_emit_surface (surface, &src_surface);
+	    status = _cairo_pdf_surface_emit_surface (surface, &src_surface, FALSE, &is_image);
 	    if (unlikely (status))
 		return status;
 	}
+
+	if (finish) {
+	    for (; doc_surface_index < _cairo_array_num_elements (&surface->doc_surfaces); doc_surface_index++) {
+		_cairo_array_copy_element (&surface->doc_surfaces, doc_surface_index, &src_surface);
+		status = _cairo_pdf_surface_emit_surface (surface, &src_surface, FALSE, &is_image);
+		if (unlikely (status))
+		    return status;
+	    }
+	}
     }
 
     return CAIRO_STATUS_SUCCESS;
@@ -6349,10 +6855,15 @@
 static cairo_int_status_t
 _cairo_pdf_surface_write_page (cairo_pdf_surface_t *surface)
 {
-    cairo_pdf_resource_t page, knockout, res;
+    cairo_pdf_resource_t knockout, res, thumbnail_res;
+    cairo_pdf_resource_t *page;
     cairo_int_status_t status;
-    unsigned int i, len;
+    unsigned int i, len, page_num, num_annots;
 
+    status = _cairo_pdf_interchange_write_page_objects (surface);
+    if (unlikely (status))
+	return status;
+
     _cairo_pdf_group_resources_clear (&surface->resources);
     if (surface->has_fallback_images) {
 	cairo_rectangle_int_t extents;
@@ -6362,7 +6873,7 @@
 	extents.y = 0;
 	extents.width = ceil (surface->width);
 	extents.height = ceil (surface->height);
-	_get_bbox_from_extents (surface->height, &extents, &bbox);
+	_get_bbox_from_extents (&extents, &bbox);
 	status = _cairo_pdf_surface_open_knockout_group (surface, &bbox);
 	if (unlikely (status))
 	    return status;
@@ -6405,13 +6916,22 @@
 	    return status;
     }
 
-    page = _cairo_pdf_surface_new_object (surface);
-    if (page.id == 0)
-	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
+    thumbnail_res.id = 0;
+    if (surface->thumbnail_image) {
+	cairo_pdf_source_surface_entry_t entry;
 
+	memset (&entry, 0, sizeof (entry));
+	thumbnail_res = _cairo_pdf_surface_new_object (surface);
+	entry.surface_res = thumbnail_res;
+	_cairo_pdf_surface_emit_image (surface, surface->thumbnail_image, &entry);
+    }
+
+    page_num = _cairo_array_num_elements (&surface->pages);
+    page = _cairo_array_index (&surface->pages, page_num - 1);
+    _cairo_pdf_surface_update_object (surface, *page);
     _cairo_output_stream_printf (surface->output,
 				 "%d 0 obj\n"
-				 "<< /Type /Page\n"
+				 "<< /Type /Page %% %d\n"
 				 "   /Parent %d 0 R\n"
 				 "   /MediaBox [ 0 0 %f %f ]\n"
 				 "   /Contents %d 0 R\n"
@@ -6421,10 +6941,9 @@
 				 "      /I true\n"
 				 "      /CS /DeviceRGB\n"
 				 "   >>\n"
-				 "   /Resources %d 0 R\n"
-				 ">>\n"
-				 "endobj\n",
-				 page.id,
+				 "   /Resources %d 0 R\n",
+				 page->id,
+				 page_num,
 				 surface->pages_resource.id,
 				 surface->width,
 				 surface->height,
@@ -6431,11 +6950,36 @@
 				 surface->content.id,
 				 surface->content_resources.id);
 
-    status = _cairo_array_append (&surface->pages, &page);
-    if (unlikely (status))
-	return status;
+    if (surface->page_parent_tree >= 0) {
+	_cairo_output_stream_printf (surface->output,
+				     "   /StructParents %d\n",
+				     surface->page_parent_tree);
+    }
 
-    status = _cairo_pdf_surface_write_patterns_and_smask_groups (surface);
+    num_annots = _cairo_array_num_elements (&surface->page_annots);
+    if (num_annots > 0) {
+	_cairo_output_stream_printf (surface->output,
+				     "   /Annots [ ");
+	for (i = 0; i < num_annots; i++) {
+	    _cairo_array_copy_element (&surface->page_annots, i, &res);
+	    _cairo_output_stream_printf (surface->output,
+					 "%d 0 R ",
+					 res.id);
+	}
+	_cairo_output_stream_printf (surface->output, "]\n");
+    }
+
+    if (thumbnail_res.id) {
+	_cairo_output_stream_printf (surface->output,
+				     "   /Thumb %d 0 R\n",
+				     thumbnail_res.id);
+    }
+
+    _cairo_output_stream_printf (surface->output,
+				 ">>\n"
+				 "endobj\n");
+
+    status = _cairo_pdf_surface_write_patterns_and_smask_groups (surface, FALSE);
     if (unlikely (status))
 	return status;
 
@@ -6444,7 +6988,7 @@
 
 static cairo_int_status_t
 _cairo_pdf_surface_analyze_surface_pattern_transparency (cairo_pdf_surface_t      *surface,
-							 cairo_surface_pattern_t *pattern)
+							 cairo_surface_pattern_t  *pattern)
 {
     cairo_image_surface_t  *image;
     void		   *image_extra;
@@ -6677,7 +7221,11 @@
     bbox.p1.y = 0;
     bbox.p2.x = surface->width;
     bbox.p2.y = surface->height;
-    return _cairo_pdf_surface_open_content_stream (surface, &bbox, NULL, TRUE, TRUE);
+    status = _cairo_pdf_surface_open_content_stream (surface, &bbox, NULL, TRUE, TRUE);
+    if (unlikely (status))
+	return status;
+
+    return _cairo_pdf_interchange_begin_page_content (surface);
 }
 
 /* If source is an opaque image and mask is an image and both images
@@ -6694,7 +7242,6 @@
     cairo_image_surface_t  *image;
     void		   *image_extra;
     cairo_image_transparency_t transparency;
-    cairo_pdf_resource_t smask_res;
     int src_width, src_height;
     int mask_width, mask_height;
     double src_x_offset, src_y_offset;
@@ -6703,8 +7250,8 @@
     double mask_x1, mask_y1, mask_x2, mask_y2;
     cairo_matrix_t p2u;
     double src_radius, mask_radius, e;
-    cairo_rectangle_int_t extents2;
     cairo_bool_t need_smask;
+    cairo_pdf_source_surface_entry_t *pdf_source;
 
     /* Check that source and mask are images */
 
@@ -6823,16 +7370,15 @@
 							mask,
 							op,
 							source->filter,
-							FALSE,
-							TRUE,
+							FALSE, /* stencil mask */
+							TRUE, /* smask */
+							FALSE, /* need_transp_group */
 							extents,
+							NULL, /* smask_res */
+							&pdf_source,
 							NULL,
-							&smask_res,
-							&mask_width,
-							&mask_height,
-							&mask_x_offset,
-							&mask_y_offset,
-							&extents2);
+							NULL,
+							NULL);
 	if (unlikely (status))
 	    return status;
     }
@@ -6843,7 +7389,8 @@
 
     _cairo_output_stream_printf (surface->output, "q\n");
     status = _cairo_pdf_surface_paint_surface_pattern (surface, op, source, extents,
-						       need_smask ? &smask_res : NULL,
+						       1.0, /* alpha */
+						       need_smask ? &pdf_source->surface_res : NULL,
 						       FALSE);
     if (unlikely (status))
 	return status;
@@ -6906,7 +7453,7 @@
 	return status;
 
     _cairo_output_stream_printf (surface->output, "q\n");
-    status = _cairo_pdf_surface_paint_surface_pattern (surface, op, mask, extents, NULL, TRUE);
+    status = _cairo_pdf_surface_paint_surface_pattern (surface, op, mask, extents, 1.0, NULL, TRUE);
     if (unlikely (status))
 	return status;
 
@@ -6956,11 +7503,15 @@
     if (unlikely (status))
 	return status;
 
+    status = _cairo_pdf_interchange_add_operation_extents (surface, &extents.bounded);
+    if (unlikely (status))
+	return status;
+
     if (surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE) {
 	status = _cairo_pdf_surface_analyze_operation (surface, op, source, &extents.bounded);
 	goto cleanup;
     } else if (surface->paginated_mode == CAIRO_PAGINATED_MODE_FALLBACK) {
-	status = _cairo_pdf_surface_start_fallback (surface);
+	status = _cairo_pdf_surface_start_fallback  (surface);
 	if (unlikely (status))
 	    goto cleanup;
     }
@@ -6985,7 +7536,8 @@
 						   op,
 						   source,
 						   &extents.bounded,
-						   FALSE);
+						   1.0, /* alpha */
+						   FALSE); /* mask */
 	if (unlikely (status))
 	    goto cleanup;
 
@@ -7041,8 +7593,11 @@
 	    goto cleanup;
 
 	_cairo_output_stream_printf (surface->output,
-				     "0 0 %f %f re f\n",
-				     surface->width, surface->height);
+				     "%d %d %d %d re f\n",
+				     surface->surface_extents.x,
+				     surface->surface_extents.y,
+				     surface->surface_extents.width,
+				     surface->surface_extents.height);
 
 	status = _cairo_pdf_surface_unselect_pattern (surface);
 	if (unlikely (status))
@@ -7070,6 +7625,7 @@
     cairo_int_status_t status;
     cairo_rectangle_int_t r;
     cairo_box_t box;
+    double alpha;
 
     status = _cairo_composite_rectangles_init_for_mask (&extents,
 							&surface->base,
@@ -7077,6 +7633,10 @@
     if (unlikely (status))
 	return status;
 
+    status = _cairo_pdf_interchange_add_operation_extents (surface, &extents.bounded);
+    if (unlikely (status))
+	return status;
+
     if (surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE) {
 	cairo_int_status_t source_status, mask_status;
 
@@ -7146,6 +7706,26 @@
     if (status != CAIRO_INT_STATUS_UNSUPPORTED)
 	goto cleanup;
 
+    /* Check if we can set ca/CA instead of an smask. We could handle
+     * other source patterns as well but for now this is the easiest,
+     * and most common, case to handle. */
+    if (_cairo_pattern_is_constant_alpha (mask, &extents.bounded, &alpha) &&
+	_can_paint_pattern (source)) {
+	_cairo_output_stream_printf (surface->output, "q\n");
+	status = _cairo_pdf_surface_paint_pattern (surface,
+						   op,
+						   source,
+						   &extents.bounded,
+						   alpha,
+						   FALSE); /* mask */
+	if (unlikely (status))
+	    goto cleanup;
+
+	_cairo_output_stream_printf (surface->output, "Q\n");
+	_cairo_composite_rectangles_fini (&extents);
+	return _cairo_output_stream_get_status (surface->output);
+    }
+
     group = _cairo_pdf_surface_create_smask_group (surface, &extents.bounded);
     if (unlikely (group == NULL)) {
 	status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
@@ -7246,6 +7826,10 @@
 	    goto cleanup;
     }
 
+    status = _cairo_pdf_interchange_add_operation_extents (surface, &extents.bounded);
+    if (unlikely (status))
+	goto cleanup;
+
     if (surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE) {
 	status = _cairo_pdf_surface_analyze_operation (surface, op, source, &extents.bounded);
 	goto cleanup;
@@ -7380,6 +7964,10 @@
 	    goto cleanup;
     }
 
+    status = _cairo_pdf_interchange_add_operation_extents (surface, &extents.bounded);
+    if (unlikely (status))
+	goto cleanup;
+
     if (surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE) {
 	status = _cairo_pdf_surface_analyze_operation (surface, op, source, &extents.bounded);
 	goto cleanup;
@@ -7415,7 +8003,8 @@
 						   op,
 						   source,
 						   &extents.bounded,
-						   FALSE);
+						   1.0, /* alpha */
+						   FALSE); /* mask */
 	if (unlikely (status))
 	    goto cleanup;
 
@@ -7598,6 +8187,10 @@
 	    goto cleanup;
     }
 
+    status = _cairo_pdf_interchange_add_operation_extents (surface, &extents.bounded);
+    if (unlikely (status))
+	goto cleanup;
+
     fill_pattern_res.id = 0;
     gstate_res.id = 0;
     status = _cairo_pdf_surface_add_pdf_pattern (surface, fill_source,
@@ -7693,6 +8286,10 @@
     if (unlikely (status))
 	return status;
 
+    status = _cairo_pdf_interchange_add_operation_extents (surface, &extents.bounded);
+    if (unlikely (status))
+	return status;
+
     if (surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE) {
 	status = _cairo_pdf_surface_analyze_operation (surface, op, source, &extents.bounded);
 	goto cleanup;
@@ -7732,7 +8329,7 @@
 	group->source_res = pattern_res;
 
 	if (utf8_len) {
-	    group->utf8 = malloc (utf8_len);
+	    group->utf8 = _cairo_malloc (utf8_len);
 	    if (unlikely (group->utf8 == NULL)) {
 		_cairo_pdf_smask_group_destroy (group);
 		status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
@@ -7830,13 +8427,48 @@
     return _cairo_pdf_supported_mime_types;
 }
 
-static void
+static cairo_int_status_t
+_cairo_pdf_surface_tag (void			   *abstract_surface,
+			cairo_bool_t                begin,
+			const char                 *tag_name,
+			const char                 *attributes,
+			const cairo_pattern_t	   *source,
+			const cairo_stroke_style_t *style,
+			const cairo_matrix_t	   *ctm,
+			const cairo_matrix_t	   *ctm_inverse,
+			const cairo_clip_t	   *clip)
+{
+    cairo_pdf_surface_t *surface = abstract_surface;
+    cairo_int_status_t status = 0;
+
+    if (begin)
+	status = _cairo_pdf_interchange_tag_begin (surface, tag_name, attributes);
+    else
+	status = _cairo_pdf_interchange_tag_end (surface, tag_name);
+
+    return status;
+}
+
+static cairo_int_status_t
 _cairo_pdf_surface_set_paginated_mode (void			*abstract_surface,
 				       cairo_paginated_mode_t	 paginated_mode)
 {
     cairo_pdf_surface_t *surface = abstract_surface;
+    cairo_int_status_t status;
 
     surface->paginated_mode = paginated_mode;
+    status = _cairo_pdf_interchange_begin_page_content (surface);
+    if (unlikely (status))
+	return status;
+
+    if (paginated_mode == CAIRO_PAGINATED_MODE_RENDER) {
+	surface->surface_extents.x = 0;
+	surface->surface_extents.y = 0;
+	surface->surface_extents.width  = ceil (surface->width);
+	surface->surface_extents.height = ceil (surface->height);
+    }
+
+    return CAIRO_INT_STATUS_SUCCESS;
 }
 
 static const cairo_surface_backend_t cairo_pdf_surface_backend = {
@@ -7874,6 +8506,7 @@
     _cairo_pdf_surface_has_show_text_glyphs,
     _cairo_pdf_surface_show_text_glyphs,
     _cairo_pdf_surface_get_supported_mime_types,
+    _cairo_pdf_surface_tag,
 };
 
 static const cairo_paginated_surface_backend_t
@@ -7883,4 +8516,6 @@
     NULL, /* set_bounding_box */
     _cairo_pdf_surface_has_fallback_images,
     _cairo_pdf_surface_supports_fine_grained_fallbacks,
+    _cairo_pdf_surface_requires_thumbnail_image,
+    _cairo_pdf_surface_set_thumbnail_image,
 };

Modified: trunk/Build/source/libs/cairo/cairo-src/src/cairo-pdf.h
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/src/cairo-pdf.h	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/src/cairo-pdf.h	2018-10-20 03:19:36 UTC (rev 48952)
@@ -85,6 +85,73 @@
 			    double		 width_in_points,
 			    double		 height_in_points);
 
+/**
+ * cairo_pdf_outline_flags_t:
+ * @CAIRO_PDF_OUTLINE_FLAG_OPEN: The outline item defaults to open in the PDF viewer (Since 1.16)
+ * @CAIRO_PDF_OUTLINE_FLAG_BOLD: The outline item is displayed by the viewer in bold text (Since 1.16)
+ * @CAIRO_PDF_OUTLINE_FLAG_ITALIC: The outline item is displayed by the viewer in italic text (Since 1.16)
+ *
+ * #cairo_pdf_outline_flags_t is used by the
+ * cairo_pdf_surface_add_outline() function specify the attributes of
+ * an outline item. These flags may be bitwise-or'd to produce any
+ * combination of flags.
+ *
+ * Since: 1.16
+ **/
+typedef enum _cairo_pdf_outline_flags {
+    CAIRO_PDF_OUTLINE_FLAG_OPEN   = 0x1,
+    CAIRO_PDF_OUTLINE_FLAG_BOLD   = 0x2,
+    CAIRO_PDF_OUTLINE_FLAG_ITALIC = 0x4,
+} cairo_pdf_outline_flags_t;
+
+#define CAIRO_PDF_OUTLINE_ROOT 0
+
+cairo_public int
+cairo_pdf_surface_add_outline (cairo_surface_t	          *surface,
+			       int                         parent_id,
+			       const char                 *utf8,
+			       const char                 *link_attribs,
+			       cairo_pdf_outline_flags_t  flags);
+
+/**
+ * cairo_pdf_metadata_t:
+ * @CAIRO_PDF_METADATA_TITLE: The document title (Since 1.16)
+ * @CAIRO_PDF_METADATA_AUTHOR: The document author (Since 1.16)
+ * @CAIRO_PDF_METADATA_SUBJECT: The document subject (Since 1.16)
+ * @CAIRO_PDF_METADATA_KEYWORDS: The document keywords (Since 1.16)
+ * @CAIRO_PDF_METADATA_CREATOR: The document creator (Since 1.16)
+ * @CAIRO_PDF_METADATA_CREATE_DATE: The document creation date (Since 1.16)
+ * @CAIRO_PDF_METADATA_MOD_DATE: The document modification date (Since 1.16)
+ *
+ * #cairo_pdf_metadata_t is used by the
+ * cairo_pdf_surface_set_metadata() function specify the metadata to set.
+ *
+ * Since: 1.16
+ **/
+typedef enum _cairo_pdf_metadata {
+    CAIRO_PDF_METADATA_TITLE,
+    CAIRO_PDF_METADATA_AUTHOR,
+    CAIRO_PDF_METADATA_SUBJECT,
+    CAIRO_PDF_METADATA_KEYWORDS,
+    CAIRO_PDF_METADATA_CREATOR,
+    CAIRO_PDF_METADATA_CREATE_DATE,
+    CAIRO_PDF_METADATA_MOD_DATE,
+} cairo_pdf_metadata_t;
+
+cairo_public void
+cairo_pdf_surface_set_metadata (cairo_surface_t	     *surface,
+				cairo_pdf_metadata_t  metadata,
+                                const char           *utf8);
+
+cairo_public void
+cairo_pdf_surface_set_page_label (cairo_surface_t *surface,
+                                  const char      *utf8);
+
+cairo_public void
+cairo_pdf_surface_set_thumbnail_size (cairo_surface_t *surface,
+				      int              width,
+				      int              height);
+
 CAIRO_END_DECLS
 
 #else  /* CAIRO_HAS_PDF_SURFACE */

Modified: trunk/Build/source/libs/cairo/cairo-src/src/cairo-pen.c
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/src/cairo-pen.c	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/src/cairo-pen.c	2018-10-20 03:19:36 UTC (rev 48952)
@@ -106,7 +106,7 @@
 	free (pen->vertices);
 
 
-    VG (VALGRIND_MAKE_MEM_NOACCESS (pen, sizeof (cairo_pen_t)));
+    VG (VALGRIND_MAKE_MEM_UNDEFINED (pen, sizeof (cairo_pen_t)));
 }
 
 cairo_status_t

Modified: trunk/Build/source/libs/cairo/cairo-src/src/cairo-png.c
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/src/cairo-png.c	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/src/cairo-png.c	2018-10-20 03:19:36 UTC (rev 48952)
@@ -136,7 +136,7 @@
 
     /* default to the most likely error */
     if (*error == CAIRO_STATUS_SUCCESS)
-	*error = _cairo_error (CAIRO_STATUS_NO_MEMORY);
+	*error = _cairo_error (CAIRO_STATUS_PNG_ERROR);
 
 #ifdef PNG_SETJMP_SUPPORTED
     longjmp (png_jmpbuf (png), 1);
@@ -158,14 +158,6 @@
      */
 }
 
-static int
-png_setjmp (png_struct *png)
-{
-#ifdef PNG_SETJMP_SUPPORTED
-    return setjmp (png_jmpbuf (png));
-#endif
-    return 0;
-}
 
 /* Starting with libpng-1.2.30, we must explicitly specify an output_flush_fn.
  * Otherwise, we will segfault if we are writing to a stream. */
@@ -237,8 +229,10 @@
 	goto BAIL4;
     }
 
-    if (png_setjmp (png))
+#ifdef PNG_SETJMP_SUPPORTED
+    if (setjmp (png_jmpbuf (png)))
 	goto BAIL4;
+#endif
 
     png_set_write_fn (png, closure, write_func, png_simple_output_flush_fn);
 
@@ -345,7 +339,8 @@
 /**
  * cairo_surface_write_to_png:
  * @surface: a #cairo_surface_t with pixel contents
- * @filename: the name of a file to write to
+ * @filename: the name of a file to write to; on Windows this filename
+ *   is encoded in UTF-8.
  *
  * Writes the contents of @surface to a new file @filename as a PNG
  * image.
@@ -355,7 +350,8 @@
  * be allocated for the operation or
  * %CAIRO_STATUS_SURFACE_TYPE_MISMATCH if the surface does not have
  * pixel contents, or %CAIRO_STATUS_WRITE_ERROR if an I/O error occurs
- * while attempting to write the file.
+ * while attempting to write the file, or %CAIRO_STATUS_PNG_ERROR if libpng
+ * returned an error.
  *
  * Since: 1.0
  **/
@@ -372,7 +368,11 @@
     if (surface->finished)
 	return _cairo_error (CAIRO_STATUS_SURFACE_FINISHED);
 
-    fp = fopen (filename, "wb");
+    status = _cairo_fopen (filename, "wb", &fp);
+
+    if (status != CAIRO_STATUS_SUCCESS)
+	return _cairo_error (status);
+
     if (fp == NULL) {
 	switch (errno) {
 	case ENOMEM:
@@ -423,7 +423,8 @@
  * successfully.  Otherwise, %CAIRO_STATUS_NO_MEMORY is returned if
  * memory could not be allocated for the operation,
  * %CAIRO_STATUS_SURFACE_TYPE_MISMATCH if the surface does not have
- * pixel contents.
+ * pixel contents, or %CAIRO_STATUS_PNG_ERROR if libpng
+ * returned an error.
  *
  * Since: 1.0
  **/
@@ -543,11 +544,11 @@
 static cairo_surface_t *
 read_png (struct png_read_closure_t *png_closure)
 {
-    cairo_surface_t *surface;
+    cairo_surface_t * volatile surface;
     png_struct *png = NULL;
     png_info *info;
-    png_byte *data = NULL;
-    png_byte **row_pointers = NULL;
+    png_byte * volatile data = NULL;
+    png_byte ** volatile row_pointers = NULL;
     png_uint_32 png_width, png_height;
     int depth, color_type, interlace, stride;
     unsigned int i;
@@ -577,11 +578,12 @@
     png_set_read_fn (png, png_closure, stream_read_func);
 
     status = CAIRO_STATUS_SUCCESS;
-
-    if (png_setjmp (png)) {
+#ifdef PNG_SETJMP_SUPPORTED
+    if (setjmp (png_jmpbuf (png))) {
 	surface = _cairo_surface_create_in_error (status);
 	goto BAIL;
     }
+#endif
 
     png_read_info (png, info);
 
@@ -676,7 +678,7 @@
     }
 
     for (i = 0; i < png_height; i++)
-        row_pointers[i] = &data[i * stride];
+        row_pointers[i] = &data[i * (ptrdiff_t)stride];
 
     png_read_image (png, row_pointers);
     png_read_end (png, info);
@@ -736,7 +738,8 @@
 
 /**
  * cairo_image_surface_create_from_png:
- * @filename: name of PNG file to load
+ * @filename: name of PNG file to load. On Windows this filename
+ *   is encoded in UTF-8.
  *
  * Creates a new image surface and initializes the contents to the
  * given PNG file.
@@ -749,6 +752,7 @@
  *	%CAIRO_STATUS_NO_MEMORY
  *	%CAIRO_STATUS_FILE_NOT_FOUND
  *	%CAIRO_STATUS_READ_ERROR
+ *	%CAIRO_STATUS_PNG_ERROR
  *
  * Alternatively, you can allow errors to propagate through the drawing
  * operations and check the status on the context upon completion
@@ -761,10 +765,14 @@
 {
     struct png_read_closure_t png_closure;
     cairo_surface_t *surface;
+    cairo_status_t status;
 
-    png_closure.closure = fopen (filename, "rb");
+    status = _cairo_fopen (filename, "rb", (FILE **) &png_closure.closure);
+
+    if (status != CAIRO_STATUS_SUCCESS)
+	return _cairo_surface_create_in_error (status);
+
     if (png_closure.closure == NULL) {
-	cairo_status_t status;
 	switch (errno) {
 	case ENOMEM:
 	    status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
@@ -804,6 +812,7 @@
  *
  *	%CAIRO_STATUS_NO_MEMORY
  *	%CAIRO_STATUS_READ_ERROR
+ *	%CAIRO_STATUS_PNG_ERROR
  *
  * Alternatively, you can allow errors to propagate through the drawing
  * operations and check the status on the context upon completion

Modified: trunk/Build/source/libs/cairo/cairo-src/src/cairo-polygon-intersect.c
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/src/cairo-polygon-intersect.c	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/src/cairo-polygon-intersect.c	2018-10-20 03:19:36 UTC (rev 48952)
@@ -447,7 +447,7 @@
        HAVE_BX      = 0x2,
        HAVE_BOTH    = HAVE_AX | HAVE_BX
     } have_ax_bx = HAVE_BOTH;
-    int32_t ax, bx;
+    int32_t ax = 0, bx = 0;
 
     if (y == a->edge.line.p1.y)
 	ax = a->edge.line.p1.x;
@@ -1107,6 +1107,7 @@
 			 int			 top,
 			 cairo_polygon_t	*polygon)
 {
+    assert (right != NULL);
     assert (right->deferred.other == NULL);
 
     if (left->deferred.other == right)
@@ -1113,7 +1114,7 @@
 	return;
 
     if (left->deferred.other != NULL) {
-	if (right != NULL && edges_colinear (left->deferred.other, right)) {
+	if (edges_colinear (left->deferred.other, right)) {
 	    cairo_bo_edge_t *old = left->deferred.other;
 
 	    /* continuation on right, extend right to cover both */
@@ -1131,7 +1132,7 @@
 	edges_end (left, top, polygon);
     }
 
-    if (right != NULL && ! edges_colinear (left, right)) {
+    if (! edges_colinear (left, right)) {
 	left->deferred.top = top;
 	left->deferred.other = right;
     }

Modified: trunk/Build/source/libs/cairo/cairo-src/src/cairo-polygon-reduce.c
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/src/cairo-polygon-reduce.c	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/src/cairo-polygon-reduce.c	2018-10-20 03:19:36 UTC (rev 48952)
@@ -445,7 +445,7 @@
        HAVE_BX      = 0x2,
        HAVE_BOTH    = HAVE_AX | HAVE_BX
     } have_ax_bx = HAVE_BOTH;
-    int32_t ax, bx;
+    int32_t ax = 0, bx = 0;
 
     if (y == a->edge.line.p1.y)
 	ax = a->edge.line.p1.x;

Modified: trunk/Build/source/libs/cairo/cairo-src/src/cairo-polygon.c
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/src/cairo-polygon.c	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/src/cairo-polygon.c	2018-10-20 03:19:36 UTC (rev 48952)
@@ -248,7 +248,7 @@
     if (polygon->edges != polygon->edges_embedded)
 	free (polygon->edges);
 
-    VG (VALGRIND_MAKE_MEM_NOACCESS (polygon, sizeof (cairo_polygon_t)));
+    VG (VALGRIND_MAKE_MEM_UNDEFINED (polygon, sizeof (cairo_polygon_t)));
 }
 
 /* make room for at least one more edge */

Modified: trunk/Build/source/libs/cairo/cairo-src/src/cairo-ps-surface-private.h
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/src/cairo-ps-surface-private.h	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/src/cairo-ps-surface-private.h	2018-10-20 03:19:36 UTC (rev 48952)
@@ -49,6 +49,19 @@
 
 #include <time.h>
 
+typedef struct _cairo_ps_form {
+    cairo_hash_entry_t base;
+    unsigned char *unique_id;
+    unsigned long unique_id_length;
+    cairo_bool_t is_image;
+    int id;
+    cairo_surface_t *src_surface;
+    cairo_filter_t filter;
+
+    /* Union of source extents required for all operations using this form */
+    cairo_rectangle_int_t required_extents;
+} cairo_ps_form_t;
+
 typedef struct cairo_ps_surface {
     cairo_surface_t base;
 
@@ -63,15 +76,16 @@
     cairo_output_stream_t *stream;
 
     cairo_bool_t eps;
+    cairo_bool_t contains_eps;
     cairo_content_t content;
     double width;
     double height;
-    cairo_rectangle_int_t page_bbox;
-    int bbox_x1, bbox_y1, bbox_x2, bbox_y2;
+    cairo_point_int_t document_bbox_p1, document_bbox_p2; /* in PS coordinates */
+    cairo_rectangle_int_t surface_extents;
+    cairo_bool_t surface_bounded;
     cairo_matrix_t cairo_to_ps;
+    cairo_bool_t paint_proc; /* TRUE if surface will be used in a PaintProc */
 
-    cairo_bool_t use_string_datasource;
-
     cairo_bool_t current_pattern_is_solid_color;
     cairo_color_t current_color;
 
@@ -90,6 +104,8 @@
     cairo_array_t dsc_setup_comments;
     cairo_array_t dsc_page_setup_comments;
 
+    cairo_array_t recording_surf_stack;
+
     cairo_array_t *dsc_comment_target;
 
     cairo_ps_level_t ps_level;
@@ -99,6 +115,9 @@
 
     cairo_pdf_operators_t pdf_operators;
     cairo_surface_t *paginated_surface;
+    cairo_hash_table_t *forms;
+    int num_forms;
+    long total_form_size;
 } cairo_ps_surface_t;
 
 #endif /* CAIRO_PS_SURFACE_PRIVATE_H */

Modified: trunk/Build/source/libs/cairo/cairo-src/src/cairo-ps-surface.c
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/src/cairo-ps-surface.c	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/src/cairo-ps-surface.c	2018-10-20 03:19:36 UTC (rev 48952)
@@ -77,6 +77,7 @@
 #include "cairo-output-stream-private.h"
 #include "cairo-type3-glyph-surface-private.h"
 #include "cairo-image-info-private.h"
+#include "cairo-tag-attributes-private.h"
 
 #include <stdio.h>
 #include <ctype.h>
@@ -84,8 +85,15 @@
 #include <zlib.h>
 #include <errno.h>
 
-#define DEBUG_PS 0
+/* Forms are emitted at the start and stored in memory so we limit the
+ * total size of all forms to prevent running out of memory. If this
+ * limit is exceeded, surfaces that would be stored in forms are
+ * emitted each time the surface is used. */
+#define MAX_L2_FORM_DATA (256*1024)
+#define MAX_L3_FORM_DATA (2*1024*1024) /* Assume Level 3 printers have more memory */
 
+/* #define DEBUG_PS 1 */
+
 #if DEBUG_PS
 #define DEBUG_FALLBACK(s) \
     fprintf (stderr, "%s::%d -- %s\n", __FUNCTION__, __LINE__, (s))
@@ -105,11 +113,44 @@
  *
  * The PostScript surface is used to render cairo graphics to Adobe
  * PostScript files and is a multi-page vector surface backend.
+ *
+ * The following mime types are supported: %CAIRO_MIME_TYPE_JPEG,
+ * %CAIRO_MIME_TYPE_UNIQUE_ID,
+ * %CAIRO_MIME_TYPE_CCITT_FAX, %CAIRO_MIME_TYPE_CCITT_FAX_PARAMS,
+ * %CAIRO_MIME_TYPE_CCITT_FAX, %CAIRO_MIME_TYPE_CCITT_FAX_PARAMS,
+ * %CAIRO_MIME_TYPE_EPS, %CAIRO_MIME_TYPE_EPS_PARAMS.
+ *
+ * Source surfaces used by the PostScript surface that have a
+ * %CAIRO_MIME_TYPE_UNIQUE_ID mime type will be stored in PostScript
+ * printer memory for the duration of the print
+ * job. %CAIRO_MIME_TYPE_UNIQUE_ID should only be used for small
+ * frequently used sources.
+ *
+ * The %CAIRO_MIME_TYPE_CCITT_FAX and %CAIRO_MIME_TYPE_CCITT_FAX_PARAMS mime types
+ * are documented in [CCITT Fax Images][ccitt].
+ *
+ * # Embedding EPS files # {#eps}
+ *
+ * Encapsulated PostScript files can be embedded in the PS output by
+ * setting the CAIRO_MIME_TYPE_EPS mime data on a surface to the EPS
+ * data and painting the surface.  The EPS will be scaled and
+ * translated to the extents of the surface the EPS data is attached
+ * to.
+ *
+ * The %CAIRO_MIME_TYPE_EPS mime type requires the
+ * %CAIRO_MIME_TYPE_EPS_PARAMS mime data to also be provided in order
+ * to specify the embeddding parameters.  %CAIRO_MIME_TYPE_EPS_PARAMS
+ * mime data must contain a string of the form "bbox=[llx lly urx
+ * ury]" that specifies the bounding box (in PS coordinates) of the
+ * EPS graphics. The parameters are: lower left x, lower left y, upper
+ * right x, upper right y. Normally the bbox data is identical to the
+ * %%%BoundingBox data in the EPS file.
+ *
  **/
 
 /**
  * CAIRO_HAS_PS_SURFACE:
- * 
+ *
  * Defined if the PostScript surface backend is available.
  * This macro can be used to conditionally compile backend-specific code.
  *
@@ -120,8 +161,31 @@
     CAIRO_PS_COMPRESS_NONE,
     CAIRO_PS_COMPRESS_LZW,
     CAIRO_PS_COMPRESS_DEFLATE
- } cairo_ps_compress_t;
+} cairo_ps_compress_t;
 
+typedef enum {
+    CAIRO_EMIT_SURFACE_ANALYZE,
+    CAIRO_EMIT_SURFACE_EMIT,
+    CAIRO_EMIT_SURFACE_EMIT_FORM
+} cairo_emit_surface_mode_t;
+
+typedef struct  {
+    /* input params */
+    cairo_surface_t *src_surface;
+    cairo_operator_t op;
+    const cairo_rectangle_int_t *src_surface_extents;
+    cairo_bool_t src_surface_bounded;
+    const cairo_rectangle_int_t *src_op_extents; /* operation extents in src space */
+    cairo_filter_t filter;
+    cairo_bool_t stencil_mask; /* TRUE if source is to be used as a mask */
+
+    /* output params */
+    cairo_bool_t is_image; /* returns TRUE if PS image will be emitted */
+                           /*         FALSE if recording will be emitted */
+    long approx_size;
+    int eod_count;
+} cairo_emit_surface_params_t;
+
 static const cairo_surface_backend_t cairo_ps_surface_backend;
 static const cairo_paginated_surface_backend_t cairo_ps_surface_paginated_backend;
 
@@ -129,6 +193,9 @@
 _cairo_ps_surface_get_extents (void		       *abstract_surface,
 			       cairo_rectangle_int_t   *rectangle);
 
+static void
+_cairo_ps_form_emit (void *entry, void *closure);
+
 static const cairo_ps_level_t _cairo_ps_levels[] =
 {
     CAIRO_PS_LEVEL_2,
@@ -146,6 +213,8 @@
 static const char *_cairo_ps_supported_mime_types[] =
 {
     CAIRO_MIME_TYPE_JPEG,
+    CAIRO_MIME_TYPE_CCITT_FAX,
+    CAIRO_MIME_TYPE_CCITT_FAX_PARAMS,
     NULL
 };
 
@@ -184,6 +253,40 @@
 } cairo_page_media_t;
 
 static void
+_cairo_ps_form_init_key (cairo_ps_form_t *key)
+{
+    key->base.hash = _cairo_hash_bytes (_CAIRO_HASH_INIT_VALUE,
+					key->unique_id, key->unique_id_length);
+}
+
+static cairo_bool_t
+_cairo_ps_form_equal (const void *key_a, const void *key_b)
+{
+    const cairo_ps_form_t *a = key_a;
+    const cairo_ps_form_t *b = key_b;
+
+    if (a->filter != b->filter)
+	return FALSE;
+
+    if (a->unique_id_length != b->unique_id_length)
+	return FALSE;
+
+    return memcmp (a->unique_id, b->unique_id, a->unique_id_length) == 0;
+}
+
+static void
+_cairo_ps_form_pluck (void *entry, void *closure)
+{
+    cairo_ps_form_t *surface_entry = entry;
+    cairo_hash_table_t *patterns = closure;
+
+    _cairo_hash_table_remove (patterns, &surface_entry->base);
+    free (surface_entry->unique_id);
+    cairo_surface_destroy (surface_entry->src_surface);
+    free (surface_entry);
+}
+
+static void
 _cairo_ps_surface_emit_header (cairo_ps_surface_t *surface)
 {
     char ctime_buf[26];
@@ -209,7 +312,7 @@
 
     _cairo_output_stream_printf (surface->final_stream,
 				 "%%!PS-Adobe-3.0%s\n"
-				 "%%%%Creator: cairo %s (http://cairographics.org)\n"
+				 "%%%%Creator: cairo %s (https://cairographics.org)\n"
 				 "%%%%CreationDate: %s"
 				 "%%%%Pages: %d\n",
 				 eps_header,
@@ -259,10 +362,10 @@
     if (!has_bbox) {
 	_cairo_output_stream_printf (surface->final_stream,
 				     "%%%%BoundingBox: %d %d %d %d\n",
-				     surface->bbox_x1,
-				     surface->bbox_y1,
-				     surface->bbox_x2,
-				     surface->bbox_y2);
+				     surface->document_bbox_p1.x,
+				     surface->document_bbox_p1.y,
+				     surface->document_bbox_p2.x,
+				     surface->document_bbox_p2.y);
     }
 
     _cairo_output_stream_printf (surface->final_stream,
@@ -273,7 +376,6 @@
 
     if (surface->eps) {
 	_cairo_output_stream_printf (surface->final_stream,
-				     "save\n"
 				     "50 dict begin\n");
     } else {
 	_cairo_output_stream_printf (surface->final_stream,
@@ -309,9 +411,6 @@
 				 "/W* { eoclip } bind def\n"
 				 "/BT { } bind def\n"
 				 "/ET { } bind def\n"
-				 "/pdfmark where { pop globaldict /?pdfmark /exec load put }\n"
-				 "    { globaldict begin /?pdfmark /pop load def /pdfmark\n"
-				 "    /cleartomark load def end } ifelse\n"
 				 "/BDC { mark 3 1 roll /BDC pdfmark } bind def\n"
 				 "/EMC { mark /EMC pdfmark } bind def\n"
 				 "/cairo_store_point { /cairo_point_y exch def /cairo_point_x exch def } def\n"
@@ -336,6 +435,11 @@
 				 "/g { setgray } bind def\n"
 				 "/rg { setrgbcolor } bind def\n"
 				 "/d1 { setcachedevice } bind def\n"
+				 "/cairo_data_source {\n"
+				 "  CairoDataIndex CairoData length lt\n"
+				 "    { CairoData CairoDataIndex get /CairoDataIndex CairoDataIndex 1 add def }\n"
+				 "    { () } ifelse\n"
+				 "} def\n"
 				 "/cairo_flush_ascii85_file { cairo_ascii85_file status { cairo_ascii85_file flushfile } if } def\n"
 				 "/cairo_image { image cairo_flush_ascii85_file } def\n"
 				 "/cairo_imagemask { imagemask cairo_flush_ascii85_file } def\n");
@@ -374,11 +478,25 @@
 				     "  } ifelse\n"
 				     "} def\n");
     }
+    if (surface->contains_eps) {
+	_cairo_output_stream_printf (surface->final_stream,
+				     "/cairo_eps_begin {\n"
+				     "  /cairo_save_state save def\n"
+				     "  /dict_count countdictstack def\n"
+				     "  /op_count count 1 sub def\n"
+				     "  userdict begin\n"
+				     "  /showpage { } def\n"
+				     "  0 g 0 J 1 w 0 j 10 M [ ] 0 d n\n"
+				     "} bind def\n"
+				     "/cairo_eps_end {\n"
+				     "  count op_count sub { pop } repeat\n"
+				     "  countdictstack dict_count sub { end } repeat\n"
+				     "  cairo_save_state restore\n"
+				     "} bind def\n");
+    }
 
     _cairo_output_stream_printf (surface->final_stream,
 				 "%%%%EndProlog\n");
-    _cairo_output_stream_printf (surface->final_stream,
-				 "%%%%BeginSetup\n");
 
     num_comments = _cairo_array_num_elements (&surface->dsc_setup_comments);
     if (num_comments) {
@@ -673,7 +791,7 @@
     _cairo_output_stream_printf (surface->final_stream,
 				 "8 dict begin\n"
 				 "/FontType 3 def\n"
-				 "/FontMatrix [1 0 0 1 0 0] def\n"
+				 "/FontMatrix [1 0 0 -1 0 0] def\n"
 				 "/Encoding 256 array def\n"
 				 "0 1 255 { Encoding exch /.notdef put } for\n");
 
@@ -836,6 +954,16 @@
 						    surface);
 }
 
+
+static cairo_int_status_t
+_cairo_ps_surface_emit_forms (cairo_ps_surface_t *surface)
+{
+    _cairo_hash_table_foreach (surface->forms,
+			       _cairo_ps_form_emit,
+			       surface);
+    return surface->base.status;
+}
+
 static cairo_status_t
 _cairo_ps_surface_emit_body (cairo_ps_surface_t *surface)
 {
@@ -863,7 +991,7 @@
 
     if (surface->eps) {
 	_cairo_output_stream_printf (surface->final_stream,
-				     "end restore\n");
+				     "end\n");
     }
 
     _cairo_output_stream_printf (surface->final_stream,
@@ -882,11 +1010,11 @@
 	_cairo_box_round_to_rectangle (&box, &rect);
 
 	/* skip trivial whole-page clips */
-	if (_cairo_rectangle_intersect (&rect, &surface->page_bbox)) {
-	    if (rect.x == surface->page_bbox.x &&
-		rect.width == surface->page_bbox.width &&
-		rect.y == surface->page_bbox.y &&
-		rect.height == surface->page_bbox.height)
+	if (_cairo_rectangle_intersect (&rect, &surface->surface_extents)) {
+	    if (rect.x == surface->surface_extents.x &&
+		rect.width == surface->surface_extents.width &&
+		rect.y == surface->surface_extents.y &&
+		rect.height == surface->surface_extents.height)
 	    {
 		return TRUE;
 	    }
@@ -975,7 +1103,7 @@
 	}
     }
 
-    page = malloc (sizeof (cairo_page_media_t));
+    page = _cairo_malloc (sizeof (cairo_page_media_t));
     if (unlikely (page == NULL)) {
 	_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
 	return NULL;
@@ -1011,7 +1139,7 @@
     cairo_status_t status, status_ignored;
     cairo_ps_surface_t *surface;
 
-    surface = malloc (sizeof (cairo_ps_surface_t));
+    surface = _cairo_malloc (sizeof (cairo_ps_surface_t));
     if (unlikely (surface == NULL)) {
 	status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
 	goto CLEANUP;
@@ -1020,7 +1148,8 @@
     _cairo_surface_init (&surface->base,
 			 &cairo_ps_surface_backend,
 			 NULL, /* device */
-			 CAIRO_CONTENT_COLOR_ALPHA);
+			 CAIRO_CONTENT_COLOR_ALPHA,
+			 TRUE); /* is_vector */
 
     surface->final_stream = stream;
 
@@ -1055,18 +1184,24 @@
     surface->ps_level_used = CAIRO_PS_LEVEL_2;
     surface->width  = width;
     surface->height = height;
-    cairo_matrix_init (&surface->cairo_to_ps, 1, 0, 0, -1, 0, height);
+    cairo_matrix_init (&surface->cairo_to_ps, 1, 0, 0, 1, 0, 0);
+    surface->surface_extents.x = 0;
+    surface->surface_extents.y = 0;
+    surface->surface_extents.width  = ceil (surface->width);
+    surface->surface_extents.height = ceil (surface->height);
+    surface->surface_bounded = TRUE;
     surface->paginated_mode = CAIRO_PAGINATED_MODE_ANALYZE;
     surface->force_fallbacks = FALSE;
     surface->content = CAIRO_CONTENT_COLOR_ALPHA;
-    surface->use_string_datasource = FALSE;
     surface->current_pattern_is_solid_color = FALSE;
+    surface->document_bbox_p1.x = 0;
+    surface->document_bbox_p1.y = 0;
+    surface->document_bbox_p2.x = 0;
+    surface->document_bbox_p2.y = 0;
+    surface->total_form_size = 0;
+    surface->contains_eps = FALSE;
+    surface->paint_proc = FALSE;
 
-    surface->page_bbox.x = 0;
-    surface->page_bbox.y = 0;
-    surface->page_bbox.width  = width;
-    surface->page_bbox.height = height;
-
     _cairo_surface_clipper_init (&surface->clipper,
 				 _cairo_ps_surface_clipper_intersect_clip_path);
 
@@ -1081,7 +1216,15 @@
     _cairo_array_init (&surface->dsc_header_comments, sizeof (char *));
     _cairo_array_init (&surface->dsc_setup_comments, sizeof (char *));
     _cairo_array_init (&surface->dsc_page_setup_comments, sizeof (char *));
+    _cairo_array_init (&surface->recording_surf_stack, sizeof (unsigned int));
 
+    surface->num_forms = 0;
+    surface->forms = _cairo_hash_table_create (_cairo_ps_form_equal);
+    if (unlikely (surface->forms == NULL)) {
+	status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
+	goto CLEANUP_FONT_SUBSETS;
+    }
+
     surface->dsc_comment_target = &surface->dsc_header_comments;
 
     surface->paginated_surface = _cairo_paginated_surface_create (
@@ -1095,6 +1238,7 @@
 	return surface->paginated_surface;
     }
 
+ CLEANUP_FONT_SUBSETS:
     _cairo_scaled_font_subsets_destroy (surface->font_subsets);
  CLEANUP_OUTPUT_STREAM:
     status_ignored = _cairo_output_stream_destroy (surface->stream);
@@ -1403,7 +1547,11 @@
 
     ps_surface->width = width_in_points;
     ps_surface->height = height_in_points;
-    cairo_matrix_init (&ps_surface->cairo_to_ps, 1, 0, 0, -1, 0, height_in_points);
+    cairo_matrix_init (&ps_surface->cairo_to_ps, 1, 0, 0, 1, 0, 0);
+    ps_surface->surface_extents.x = 0;
+    ps_surface->surface_extents.y = 0;
+    ps_surface->surface_extents.width  = ceil (ps_surface->width);
+    ps_surface->surface_extents.height = ceil (ps_surface->height);
     _cairo_pdf_operators_set_cairo_to_pdf_matrix (&ps_surface->pdf_operators,
 						  &ps_surface->cairo_to_ps);
     status = _cairo_paginated_surface_set_size (ps_surface->paginated_surface,
@@ -1613,10 +1761,17 @@
 
     _cairo_ps_surface_emit_header (surface);
 
+    _cairo_output_stream_printf (surface->final_stream,
+				 "%%%%BeginSetup\n");
+
     status = _cairo_ps_surface_emit_font_subsets (surface);
     if (unlikely (status))
 	goto CLEANUP;
 
+    status = _cairo_ps_surface_emit_forms (surface);
+    if (unlikely (status))
+	goto CLEANUP;
+
     _cairo_output_stream_printf (surface->final_stream,
 				 "%%%%EndSetup\n");
 
@@ -1627,6 +1782,10 @@
     _cairo_ps_surface_emit_footer (surface);
 
 CLEANUP:
+    _cairo_hash_table_foreach (surface->forms,
+			       _cairo_ps_form_pluck,
+			       surface->forms);
+    _cairo_hash_table_destroy (surface->forms);
     _cairo_scaled_font_subsets_destroy (surface->font_subsets);
 
     status2 = _cairo_output_stream_destroy (surface->stream);
@@ -1668,6 +1827,8 @@
 	free (comments[i]);
     _cairo_array_fini (&surface->dsc_page_setup_comments);
 
+    _cairo_array_fini (&surface->recording_surf_stack);
+
     _cairo_surface_clipper_reset (&surface->clipper);
 
     return status;
@@ -1715,102 +1876,87 @@
 
 /**
  * _cairo_ps_surface_acquire_source_surface_from_pattern:
- * @surface: the ps surface
- * @pattern: A #cairo_pattern_t of type SURFACE or RASTER_SOURCE to use as the source
- * @extents: extents of the operation that is using this source
- * @width: returns width of surface
- * @height: returns height of surface
- * @x_offset: returns x offset of surface
- * @y_offset: returns y offset of surface
- * @surface: returns surface of type image surface or recording surface
- * @image_extra: returns image extra for image type surface
+ * @surface: [in] the ps surface
+ * @pattern: [in] A #cairo_pattern_t of type SURFACE or RASTER_SOURCE to use
+ *                as the source
+ * @extents: [in] extents of the operation that is using this source
+ * @src_surface_extents: [out] return source surface extents
+ * @src_surface_bounded: [out] return TRUE if source surface is bounded
+ * @src_op_extents: [out] return operation extents in source space
+ * @source_surface: [out] returns surface of type image surface or recording surface
+ * @x_offset: [out] return x offset of surface
+ * @y_offset: [out] return y offset of surface
  *
  * Acquire source surface or raster source pattern.
  **/
 static cairo_status_t
-_cairo_ps_surface_acquire_source_surface_from_pattern (cairo_ps_surface_t           *surface,
-						       const cairo_pattern_t        *pattern,
-						       const cairo_rectangle_int_t  *extents,
-						       int                          *width,
-						       int                          *height,
-						       double                       *x_offset,
-						       double                       *y_offset,
-						       cairo_surface_t             **source_surface,
-						       void                        **image_extra)
+_cairo_ps_surface_acquire_source_surface_from_pattern (
+    cairo_ps_surface_t           *surface,
+    const cairo_pattern_t        *pattern,
+    const cairo_rectangle_int_t  *extents,
+    cairo_rectangle_int_t        *src_surface_extents,
+    cairo_bool_t                 *src_surface_bounded,
+    cairo_rectangle_int_t        *src_op_extents,
+    cairo_surface_t             **source_surface,
+    double                       *x_offset,
+    double                       *y_offset)
 {
-    cairo_status_t          status;
-    cairo_image_surface_t  *image;
+    cairo_status_t status;
+    cairo_box_t bbox;
 
-    *x_offset = *y_offset = 0;
-    switch (pattern->type) {
-    case CAIRO_PATTERN_TYPE_SURFACE: {
-	cairo_surface_t *surf = ((cairo_surface_pattern_t *) pattern)->surface;
+    *x_offset = 0;
+    *y_offset = 0;
 
+    /* get the operation extents in pattern space */
+    _cairo_box_from_rectangle (&bbox, extents);
+    _cairo_matrix_transform_bounding_box_fixed (&pattern->matrix, &bbox, NULL);
+    _cairo_box_round_to_rectangle (&bbox, src_op_extents);
+
+    if (pattern->type == CAIRO_PATTERN_TYPE_RASTER_SOURCE) {
+	cairo_surface_t *surf;
+
+	surf = _cairo_raster_source_pattern_acquire (pattern, &surface->base, src_op_extents);
+	if (!surf)
+	    return CAIRO_INT_STATUS_UNSUPPORTED;
+
+	*src_surface_bounded = _cairo_surface_get_extents (surf, src_surface_extents);
+	cairo_surface_get_device_offset (surf, x_offset, y_offset);
+	*source_surface = surf;
+    } else if (pattern->type == CAIRO_PATTERN_TYPE_SURFACE) {
+	cairo_surface_t *surf = NULL;
+
+	*source_surface = ((cairo_surface_pattern_t *) pattern)->surface;
+	surf = *source_surface;
+	*src_surface_bounded = _cairo_surface_get_extents (surf, src_surface_extents);
 	if (surf->type == CAIRO_SURFACE_TYPE_RECORDING) {
+	    if (_cairo_surface_is_snapshot (surf))
+		surf = _cairo_surface_snapshot_get_target (surf);
+
 	    if (surf->backend->type == CAIRO_SURFACE_TYPE_SUBSURFACE) {
 		cairo_surface_subsurface_t *sub = (cairo_surface_subsurface_t *) surf;
 
-		*width  = sub->extents.width;
-		*height = sub->extents.height;
-	    } else {
-		cairo_surface_t *free_me = NULL;
-		cairo_recording_surface_t *recording_surface;
-		cairo_box_t bbox;
-		cairo_rectangle_int_t extents;
+		*src_surface_extents = sub->extents;
+		*src_surface_bounded = TRUE;
+		*x_offset = -sub->extents.x;
+		*y_offset = -sub->extents.y;
+	    }
 
-		recording_surface = (cairo_recording_surface_t *) surf;
-		if (_cairo_surface_is_snapshot (&recording_surface->base)) {
-		    free_me = _cairo_surface_snapshot_get_target (&recording_surface->base);
-		    recording_surface = (cairo_recording_surface_t *) free_me;
-		}
+	    cairo_surface_destroy (surf);
+	} else if (surf->type != CAIRO_SURFACE_TYPE_IMAGE) {
+	    cairo_image_surface_t *image;
+	    void *image_extra;
 
-		status = _cairo_recording_surface_get_bbox (recording_surface, &bbox, NULL);
-		cairo_surface_destroy (free_me);
-		if (unlikely (status))
-		    return status;
-
-		_cairo_box_round_to_rectangle (&bbox, &extents);
-		*width  = extents.width;
-		*height = extents.height;
-	    }
-	    *source_surface = surf;
-
-	    return CAIRO_STATUS_SUCCESS;
-	} else {
-	    status =  _cairo_surface_acquire_source_image (surf, &image, image_extra);
+	    status = _cairo_surface_acquire_source_image (surf, &image, &image_extra);
 	    if (unlikely (status))
 		return status;
+
+	    *src_surface_bounded = _cairo_surface_get_extents (&image->base, src_surface_extents);
+	    _cairo_surface_release_source_image (surf, image, image_extra);
 	}
-    } break;
-
-    case CAIRO_PATTERN_TYPE_RASTER_SOURCE: {
-	cairo_surface_t *surf;
-	cairo_box_t box;
-	cairo_rectangle_int_t rect;
-
-	/* get the operation extents in pattern space */
-	_cairo_box_from_rectangle (&box, extents);
-	_cairo_matrix_transform_bounding_box_fixed (&pattern->matrix, &box, NULL);
-	_cairo_box_round_to_rectangle (&box, &rect);
-	surf = _cairo_raster_source_pattern_acquire (pattern, &surface->base, &rect);
-	if (!surf)
-	    return CAIRO_INT_STATUS_UNSUPPORTED;
-	assert (_cairo_surface_is_image (surf));
-	image = (cairo_image_surface_t *) surf;
-    } break;
-
-    case CAIRO_PATTERN_TYPE_SOLID:
-    case CAIRO_PATTERN_TYPE_LINEAR:
-    case CAIRO_PATTERN_TYPE_RADIAL:
-    case CAIRO_PATTERN_TYPE_MESH:
-    default:
+    } else {
 	ASSERT_NOT_REACHED;
-	break;
     }
 
-    *width = image->width;
-    *height = image->height;
-    *source_surface = &image->base;
     return CAIRO_STATUS_SUCCESS;
 }
 
@@ -1817,31 +1963,10 @@
 static void
 _cairo_ps_surface_release_source_surface_from_pattern (cairo_ps_surface_t           *surface,
 						       const cairo_pattern_t        *pattern,
-						       cairo_surface_t              *source,
-						       void                         *image_extra)
+						       cairo_surface_t              *source_surface)
 {
-    switch (pattern->type) {
-    case CAIRO_PATTERN_TYPE_SURFACE: {
-	cairo_surface_pattern_t *surf_pat = (cairo_surface_pattern_t *) pattern;
-	if (surf_pat->surface->type != CAIRO_SURFACE_TYPE_RECORDING) {
-	    cairo_image_surface_t *image  = (cairo_image_surface_t *) source;
-	    _cairo_surface_release_source_image (surf_pat->surface, image, image_extra);
-	}
-    } break;
-
-    case CAIRO_PATTERN_TYPE_RASTER_SOURCE:
-	_cairo_raster_source_pattern_release (pattern, source);
-	break;
-
-    case CAIRO_PATTERN_TYPE_SOLID:
-    case CAIRO_PATTERN_TYPE_LINEAR:
-    case CAIRO_PATTERN_TYPE_RADIAL:
-    case CAIRO_PATTERN_TYPE_MESH:
-    default:
-
-	ASSERT_NOT_REACHED;
-	break;
-    }
+    if  (pattern->type == CAIRO_PATTERN_TYPE_RASTER_SOURCE)
+	_cairo_raster_source_pattern_release (pattern, source_surface);
 }
 
 /**
@@ -1849,11 +1974,8 @@
  * @surface: the ps surface
  * @source: The source image
  * @extents: extents of the operation that is using this source
- * @width: returns width of padded image
- * @height: returns height of padded image
- * @x_offset: returns x offset of padded image
- * @y_offset: returns y offset of padded image
  * @image: returns the padded image or NULL if padding not required to fill @extents
+ * @image_extents: returns extents of padded image. These extents in are in source image space.
  *
  * Creates a padded image if the source image does not fill the extents.
  **/
@@ -1862,11 +1984,8 @@
 						  cairo_image_surface_t        *source,
 						  const cairo_matrix_t         *source_matrix,
 						  const cairo_rectangle_int_t  *extents,
-						  int                          *width,
-						  int                          *height,
-						  double                       *x_offset,
-						  double                       *y_offset,
-						  cairo_image_surface_t       **image)
+						  cairo_image_surface_t       **image,
+						  cairo_rectangle_int_t        *image_extents)
 {
     cairo_box_t box;
     cairo_rectangle_int_t rect;
@@ -1888,11 +2007,9 @@
 	_cairo_fixed_integer_floor(box.p2.y) > w ||
 	_cairo_fixed_integer_floor(box.p2.y) > h)
     {
-	pad_image =
-	    _cairo_image_surface_create_with_pixman_format (NULL,
-							    source->pixman_format,
-							    rect.width, rect.height,
-							    0);
+	pad_image = _cairo_image_surface_create_with_content (source->base.content,
+							      rect.width,
+							      rect.height);
 	if (pad_image->status)
 	    return pad_image->status;
 
@@ -1905,10 +2022,10 @@
 				       NULL);
 	_cairo_pattern_fini (&pad_pattern.base);
 	*image = (cairo_image_surface_t *) pad_image;
-	*width = rect.width;
-	*height = rect.height;
-	*x_offset = rect.x;
-	*y_offset = rect.y;
+	image_extents->x = rect.x;
+	image_extents->y = rect.y;
+	image_extents->width = rect.width;
+	image_extents->height = rect.height;
     } else {
 	*image = NULL;
 	status = CAIRO_STATUS_SUCCESS;
@@ -1922,27 +2039,32 @@
 							const cairo_pattern_t         *pattern,
 							const cairo_rectangle_int_t   *extents)
 {
-    int width, height;
+    cairo_rectangle_int_t src_surface_extents;
+    cairo_bool_t src_surface_bounded;
+    cairo_rectangle_int_t src_op_extents;
+    cairo_surface_t *source_surface;
     double x_offset, y_offset;
-    cairo_surface_t *source;
     cairo_image_surface_t *image;
     void *image_extra;
-    cairo_int_status_t      status;
+    cairo_int_status_t status;
     cairo_image_transparency_t transparency;
 
     status = _cairo_ps_surface_acquire_source_surface_from_pattern (surface,
 								    pattern,
 								    extents,
-								    &width,
-								    &height,
+								    &src_surface_extents,
+								    &src_surface_bounded,
+								    &src_op_extents,
+								    &source_surface,
 								    &x_offset,
-								    &y_offset,
-								    &source,
-								    &image_extra);
+								    &y_offset);
     if (unlikely (status))
 	return status;
 
-    image = (cairo_image_surface_t *) source;
+    status = _cairo_surface_acquire_source_image (source_surface, &image, &image_extra);
+    if (unlikely (status))
+	return status;
+
     if (image->base.status)
 	return image->base.status;
 
@@ -1969,7 +2091,8 @@
 	ASSERT_NOT_REACHED;
     }
 
-    _cairo_ps_surface_release_source_surface_from_pattern (surface, pattern, source, image_extra);
+    _cairo_surface_release_source_image (source_surface, image, image_extra);
+    _cairo_ps_surface_release_source_surface_from_pattern (surface, pattern, source_surface);
 
     return status;
 }
@@ -2156,14 +2279,9 @@
 
 /* The "standard" implementation limit for PostScript string sizes is
  * 65535 characters (see PostScript Language Reference, Appendix
- * B). We go one short of that because we sometimes need two
- * characters in a string to represent a single ASCII85 byte, (for the
- * escape sequences "\\", "\(", and "\)") and we must not split these
- * across two strings. So we'd be in trouble if we went right to the
- * limit and one of these escape sequences just happened to land at
- * the end.
+ * B).
  */
-#define STRING_ARRAY_MAX_STRING_SIZE (65535-1)
+#define STRING_ARRAY_MAX_STRING_SIZE 65535
 #define STRING_ARRAY_MAX_COLUMN	     72
 
 typedef struct _string_array_stream {
@@ -2171,64 +2289,62 @@
     cairo_output_stream_t *output;
     int column;
     int string_size;
+    int tuple_count;
     cairo_bool_t use_strings;
 } string_array_stream_t;
 
 static cairo_status_t
-_string_array_stream_write (cairo_output_stream_t *base,
-			    const unsigned char   *data,
-			    unsigned int	   length)
+_base85_string_wrap_stream_write (cairo_output_stream_t *base,
+				  const unsigned char   *data,
+				  unsigned int	   length)
 {
     string_array_stream_t *stream = (string_array_stream_t *) base;
     unsigned char c;
-    const unsigned char backslash = '\\';
 
     if (length == 0)
 	return CAIRO_STATUS_SUCCESS;
 
     while (length--) {
-	if (stream->string_size == 0 && stream->use_strings) {
-	    _cairo_output_stream_printf (stream->output, "(");
-	    stream->column++;
+	if (stream->column == 0) {
+	    if (stream->use_strings) {
+		_cairo_output_stream_printf (stream->output, "<~");
+		stream->column = 2;
+	    } else {
+		_cairo_output_stream_printf (stream->output, " ");
+		stream->column = 1;
+	    }
 	}
 
 	c = *data++;
-	if (stream->use_strings) {
-	    switch (c) {
-	    case '\\':
-	    case '(':
-	    case ')':
-		_cairo_output_stream_write (stream->output, &backslash, 1);
-		stream->column++;
-		stream->string_size++;
-		break;
+	_cairo_output_stream_write (stream->output, &c, 1);
+	stream->column++;
+
+	/* Base85 encodes each 4 byte tuple with a 5 ASCII character
+	 * tuple, except for 'z' with represents 4 zero bytes. We need
+	 * to keep track of the string length after decoding.
+	 */
+	if (c == 'z') {
+	    stream->string_size += 4;
+	    stream->tuple_count = 0;
+	} else {
+	    if (++stream->tuple_count == 5) {
+		stream->string_size += 4;
+		stream->tuple_count = 0;
 	    }
 	}
-	/* Have to be careful to never split the final ~> sequence. */
-        if (c == '~') {
-	    _cairo_output_stream_write (stream->output, &c, 1);
-	    stream->column++;
-	    stream->string_size++;
 
-	    if (length-- == 0)
-		break;
-
-	    c = *data++;
-	}
-	_cairo_output_stream_write (stream->output, &c, 1);
-	stream->column++;
-	stream->string_size++;
-
+	/* Split string at tuple boundary when there is not enough
+	 * space for another tuple */
 	if (stream->use_strings &&
-	    stream->string_size >= STRING_ARRAY_MAX_STRING_SIZE)
+	    stream->tuple_count == 0 &&
+	    stream->string_size > STRING_ARRAY_MAX_STRING_SIZE - 4)
 	{
-	    _cairo_output_stream_printf (stream->output, ")\n");
+	    _cairo_output_stream_printf (stream->output, "~>\n");
 	    stream->string_size = 0;
 	    stream->column = 0;
 	}
 	if (stream->column >= STRING_ARRAY_MAX_COLUMN) {
 	    _cairo_output_stream_printf (stream->output, "\n ");
-	    stream->string_size += 2;
 	    stream->column = 1;
 	}
     }
@@ -2237,39 +2353,32 @@
 }
 
 static cairo_status_t
-_string_array_stream_close (cairo_output_stream_t *base)
+_base85_string_wrap_stream_close (cairo_output_stream_t *base)
 {
-    cairo_status_t status;
     string_array_stream_t *stream = (string_array_stream_t *) base;
 
-    if (stream->use_strings)
-	_cairo_output_stream_printf (stream->output, ")\n");
+    if (!stream->use_strings || stream->string_size != 0)
+	_cairo_output_stream_printf (stream->output, "~>");
 
-    status = _cairo_output_stream_get_status (stream->output);
-
-    return status;
+    return _cairo_output_stream_get_status (stream->output);
 }
 
-/* A string_array_stream wraps an existing output stream. It takes the
- * data provided to it and output one or more consecutive string
- * objects, each within the standard PostScript implementation limit
- * of 65k characters.
- *
- * The strings are each separated by a space character for easy
- * inclusion within an array object, (but the array delimiters are not
- * added by the string_array_stream).
- *
+/* A _base85_strings_stream wraps an existing output stream. It takes
+ * base85 encoded data and splits it into strings each limited to
+ * STRING_ARRAY_MAX_STRING_SIZE bytes when decoded. Each string is
+ * enclosed in "<~" and "~>".
+
  * The string array stream is also careful to wrap the output within
- * STRING_ARRAY_MAX_COLUMN columns (+/- 1). The stream also adds
- * necessary escaping for special characters within a string,
- * (specifically '\', '(', and ')').
+ * STRING_ARRAY_MAX_COLUMN columns. Wrapped lines start with a space
+ * in case an encoded line starts with %% which could be interpreted
+ * as a DSC comment.
  */
 static cairo_output_stream_t *
-_string_array_stream_create (cairo_output_stream_t *output)
+_base85_strings_stream_create (cairo_output_stream_t *output)
 {
     string_array_stream_t *stream;
 
-    stream = malloc (sizeof (string_array_stream_t));
+    stream = _cairo_malloc (sizeof (string_array_stream_t));
     if (unlikely (stream == NULL)) {
 	_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
 	return (cairo_output_stream_t *) &_cairo_output_stream_nil;
@@ -2276,27 +2385,30 @@
     }
 
     _cairo_output_stream_init (&stream->base,
-			       _string_array_stream_write,
+			       _base85_string_wrap_stream_write,
 			       NULL,
-			       _string_array_stream_close);
+			       _base85_string_wrap_stream_close);
     stream->output = output;
     stream->column = 0;
     stream->string_size = 0;
+    stream->tuple_count = 0;
     stream->use_strings = TRUE;
 
     return &stream->base;
 }
 
-/* A base85_array_stream wraps an existing output stream. It wraps the
- * output within STRING_ARRAY_MAX_COLUMN columns (+/- 1). The output
- * is not enclosed in strings like string_array_stream.
+/* A base85_wrap_stream wraps an existing output stream. It wraps the
+ * output within STRING_ARRAY_MAX_COLUMN columns. A base85 EOD "~>" is
+ * appended to the end. Wrapped lines start with a space in case an
+ * encoded line starts with %% which could be interpreted as a DSC
+ * comment.
  */
 static cairo_output_stream_t *
-_base85_array_stream_create (cairo_output_stream_t *output)
+_base85_wrap_stream_create (cairo_output_stream_t *output)
 {
     string_array_stream_t *stream;
 
-    stream = malloc (sizeof (string_array_stream_t));
+    stream = _cairo_malloc (sizeof (string_array_stream_t));
     if (unlikely (stream == NULL)) {
 	_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
 	return (cairo_output_stream_t *) &_cairo_output_stream_nil;
@@ -2303,12 +2415,13 @@
     }
 
     _cairo_output_stream_init (&stream->base,
-			       _string_array_stream_write,
+			       _base85_string_wrap_stream_write,
 			       NULL,
-			       _string_array_stream_close);
+			       _base85_string_wrap_stream_close);
     stream->output = output;
     stream->column = 0;
     stream->string_size = 0;
+    stream->tuple_count = 0;
     stream->use_strings = FALSE;
 
     return &stream->base;
@@ -2370,9 +2483,9 @@
     cairo_status_t status, status2;
 
     if (use_strings)
-	string_array_stream = _string_array_stream_create (surface->stream);
+	string_array_stream = _base85_strings_stream_create (surface->stream);
     else
-	string_array_stream = _base85_array_stream_create (surface->stream);
+	string_array_stream = _base85_wrap_stream_create (surface->stream);
 
     status = _cairo_output_stream_get_status (string_array_stream);
     if (unlikely (status))
@@ -2419,9 +2532,6 @@
 	    break;
     }
     status = _cairo_output_stream_destroy (base85_stream);
-
-    /* Mark end of base85 data */
-    _cairo_output_stream_printf (string_array_stream, "~>");
     status2 = _cairo_output_stream_destroy (string_array_stream);
     if (status == CAIRO_STATUS_SUCCESS)
 	status = status2;
@@ -2429,12 +2539,32 @@
     return status;
 }
 
+static const char *
+get_interpolate (cairo_filter_t	filter)
+{
+    const char *interpolate;
+
+    switch (filter) {
+	default:
+	case CAIRO_FILTER_GOOD:
+	case CAIRO_FILTER_BEST:
+	case CAIRO_FILTER_BILINEAR:
+	    interpolate = "true";
+	    break;
+	case CAIRO_FILTER_FAST:
+	case CAIRO_FILTER_NEAREST:
+	case CAIRO_FILTER_GAUSSIAN:
+	    interpolate = "false";
+	break;
+    }
+
+    return interpolate;
+}
+
 static cairo_status_t
-_cairo_ps_surface_emit_image (cairo_ps_surface_t    *surface,
-			      cairo_image_surface_t *image_surf,
-			      cairo_operator_t	     op,
-			      cairo_filter_t         filter,
-			      cairo_bool_t           stencil_mask)
+_cairo_ps_surface_emit_image (cairo_ps_surface_t          *surface,
+			      cairo_emit_surface_mode_t    mode,
+			      cairo_emit_surface_params_t *params)
 {
     cairo_status_t status;
     unsigned char *data;
@@ -2450,11 +2580,17 @@
     const char *interpolate;
     cairo_ps_compress_t compress;
     const char *compress_filter;
+    cairo_image_surface_t *image_surf;
     cairo_image_surface_t *image;
+    void *image_extra;
 
-    if (image_surf->base.status)
-	return image_surf->base.status;
+    if (params->src_surface->status)
+	return params->src_surface->status;
 
+    status = _cairo_surface_acquire_source_image (params->src_surface, &image_surf, &image_extra);
+    if (unlikely (status))
+	return status;
+
     image  = image_surf;
     if (image->format != CAIRO_FORMAT_RGB24 &&
 	image->format != CAIRO_FORMAT_ARGB32 &&
@@ -2464,9 +2600,9 @@
 	cairo_surface_t *surf;
 	cairo_surface_pattern_t pattern;
 
-	surf = _cairo_image_surface_create_with_content (image_surf->base.content,
-							 image_surf->width,
-							 image_surf->height);
+	surf = _cairo_image_surface_create_with_content (image->base.content,
+							 image->width,
+							 image->height);
 	image = (cairo_image_surface_t *) surf;
 	if (surf->status) {
 	    status = surf->status;
@@ -2473,7 +2609,7 @@
 	    goto bail0;
 	}
 
-	_cairo_pattern_init_for_surface (&pattern, &image_surf->base);
+	_cairo_pattern_init_for_surface (&pattern, &image->base);
 	status = _cairo_surface_paint (surf,
 				       CAIRO_OPERATOR_SOURCE, &pattern.base,
 				       NULL);
@@ -2482,22 +2618,9 @@
             goto bail0;
     }
     ps_image = image;
+    interpolate = get_interpolate (params->filter);
 
-    switch (filter) {
-    default:
-    case CAIRO_FILTER_GOOD:
-    case CAIRO_FILTER_BEST:
-    case CAIRO_FILTER_BILINEAR:
-	interpolate = "true";
-	break;
-    case CAIRO_FILTER_FAST:
-    case CAIRO_FILTER_NEAREST:
-    case CAIRO_FILTER_GAUSSIAN:
-	interpolate = "false";
-	break;
-    }
-
-    if (stencil_mask) {
+    if (params->stencil_mask) {
 	use_mask = FALSE;
 	color = CAIRO_IMAGE_IS_MONOCHROME;
 	transparency = CAIRO_IMAGE_HAS_BILEVEL_ALPHA;
@@ -2508,7 +2631,7 @@
 	   current image over a white (or black for CONTENT_COLOR
 	   surfaces) RGB surface to eliminate it. */
 
-	if (op == CAIRO_OPERATOR_SOURCE ||
+	if (params->op == CAIRO_OPERATOR_SOURCE ||
 	    transparency == CAIRO_IMAGE_HAS_ALPHA ||
 	    (transparency == CAIRO_IMAGE_HAS_BILEVEL_ALPHA &&
 	     surface->ps_level == CAIRO_PS_LEVEL_2))
@@ -2550,7 +2673,7 @@
     if (use_mask)
 	data_size += (ps_image->width + 7)/8;
     data_size *= ps_image->height;
-    data = malloc (data_size);
+    data = _cairo_malloc (data_size);
     if (unlikely (data == NULL)) {
 	status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
 	goto bail1;
@@ -2558,7 +2681,7 @@
 
     i = 0;
     for (y = 0; y < ps_image->height; y++) {
-	if (stencil_mask || use_mask) {
+	if (params->stencil_mask || use_mask) {
 	    /* mask row */
 	    if (ps_image->format == CAIRO_FORMAT_A1) {
 		pixel8 = (uint8_t *) (ps_image->data + y * ps_image->stride);
@@ -2599,7 +2722,7 @@
 		    i++;
 	    }
 	}
-	if (stencil_mask)
+	if (params->stencil_mask)
 	    continue;
 
 	/* image row*/
@@ -2664,11 +2787,11 @@
 	surface->ps_level_used = CAIRO_PS_LEVEL_3;
     }
 
-    if (surface->use_string_datasource) {
+    if (surface->paint_proc) {
 	/* Emit the image data as a base85-encoded string which will
 	 * be used as the data source for the image operator later. */
 	_cairo_output_stream_printf (surface->stream,
-				     "/CairoImageData [\n");
+				     "/CairoData [\n");
 
 	status = _cairo_ps_surface_emit_base85_string (surface,
 						       data,
@@ -2681,7 +2804,7 @@
 	_cairo_output_stream_printf (surface->stream,
 				     "] def\n");
 	_cairo_output_stream_printf (surface->stream,
-				     "/CairoImageDataIndex 0 def\n");
+				     "/CairoDataIndex 0 def\n");
     } else {
 	_cairo_output_stream_printf (surface->stream,
 				     "/cairo_ascii85_file currentfile /ASCII85Decode filter def\n");
@@ -2690,17 +2813,16 @@
     if (use_mask) {
 	_cairo_output_stream_printf (surface->stream,
 				     "%s setcolorspace\n"
-				     "5 dict dup begin\n"
-				     "  /ImageType 3 def\n"
-				     "  /InterleaveType 2 def\n"
-				     "  /DataDict 8 dict def\n"
-				     "    DataDict begin\n"
-				     "    /ImageType 1 def\n"
-				     "    /Width %d def\n"
-				     "    /Height %d def\n"
-				     "    /Interpolate %s def\n"
-				     "    /BitsPerComponent %d def\n"
-				     "    /Decode [ %s ] def\n",
+				     "<<\n"
+				     "  /ImageType 3\n"
+				     "  /InterleaveType 2\n"
+				     "  /DataDict <<\n"
+				     "    /ImageType 1\n"
+				     "    /Width %d\n"
+				     "    /Height %d\n"
+				     "    /Interpolate %s\n"
+				     "    /BitsPerComponent %d\n"
+				     "    /Decode [ %s ]\n",
 				     color == CAIRO_IMAGE_IS_COLOR ? "/DeviceRGB" : "/DeviceGray",
 				     ps_image->width,
 				     ps_image->height,
@@ -2708,85 +2830,89 @@
 				     color == CAIRO_IMAGE_IS_MONOCHROME ? 1 : 8,
 				     color == CAIRO_IMAGE_IS_COLOR ? "0 1 0 1 0 1" : "0 1");
 
-	if (surface->use_string_datasource) {
+	if (surface->paint_proc) {
 	    _cairo_output_stream_printf (surface->stream,
-					 "    /DataSource {\n"
-					 "      CairoImageData CairoImageDataIndex get\n"
-					 "	/CairoImageDataIndex CairoImageDataIndex 1 add def\n"
-					 "	CairoImageDataIndex CairoImageData length 1 sub gt\n"
-					 "       { /CairoImageDataIndex 0 def } if\n"
-					 "    } /ASCII85Decode filter /%s filter def\n",
+					 "    /DataSource { cairo_data_source } /%s filter\n",
 					 compress_filter);
 	} else {
 	    _cairo_output_stream_printf (surface->stream,
-					 "    /DataSource cairo_ascii85_file /%s filter def\n",
+					 "    /DataSource cairo_ascii85_file /%s filter\n",
 					 compress_filter);
 	}
 
 	_cairo_output_stream_printf (surface->stream,
-				     "    /ImageMatrix [ 1 0 0 -1 0 %d ] def\n"
-				     "  end\n"
-				     "  /MaskDict 8 dict def\n"
-				     "     MaskDict begin\n"
-				     "    /ImageType 1 def\n"
-				     "    /Width %d def\n"
-				     "    /Height %d def\n"
-				     "    /Interpolate %s def\n"
-				     "    /BitsPerComponent 1 def\n"
-				     "    /Decode [ 1 0 ] def\n"
-				     "    /ImageMatrix [ 1 0 0 -1 0 %d ] def\n"
-				     "  end\n"
-				     "end\n"
+				     "    /ImageMatrix [ %d 0 0 %d 0 %d ]\n"
+				     "  >>\n"
+				     "  /MaskDict <<\n"
+				     "    /ImageType 1\n"
+				     "    /Width %d\n"
+				     "    /Height %d\n"
+				     "    /Interpolate %s\n"
+				     "    /BitsPerComponent 1\n"
+				     "    /Decode [ 1 0 ]\n"
+				     "    /ImageMatrix [ %d 0 0 %d 0 %d ]\n"
+				     "  >>\n"
+				     ">>\n"
 				     "image\n",
+				     ps_image->width,
+				     -ps_image->height,
 				     ps_image->height,
 				     ps_image->width,
 				     ps_image->height,
 				     interpolate,
+				     ps_image->width,
+				     -ps_image->height,
 				     ps_image->height);
     } else {
-	if (!stencil_mask) {
+	const char *decode;
+
+	if (!params->stencil_mask) {
 	    _cairo_output_stream_printf (surface->stream,
 					 "%s setcolorspace\n",
 					 color == CAIRO_IMAGE_IS_COLOR ? "/DeviceRGB" : "/DeviceGray");
 	}
+	if (params->stencil_mask)
+	    decode = "1 0";
+	else if (color == CAIRO_IMAGE_IS_COLOR)
+	    decode = "0 1 0 1 0 1";
+	else
+	    decode ="0 1";
+
 	_cairo_output_stream_printf (surface->stream,
-				     "8 dict dup begin\n"
-				     "  /ImageType 1 def\n"
-				     "  /Width %d def\n"
-				     "  /Height %d def\n"
-				     "  /Interpolate %s def\n"
-				     "  /BitsPerComponent %d def\n"
-				     "  /Decode [ %s ] def\n",
+				     "<<\n"
+				     "  /ImageType 1\n"
+				     "  /Width %d\n"
+				     "  /Height %d\n"
+				     "  /Interpolate %s\n"
+				     "  /BitsPerComponent %d\n"
+				     "  /Decode [ %s ]\n",
 				     ps_image->width,
 				     ps_image->height,
 				     interpolate,
 				     color == CAIRO_IMAGE_IS_MONOCHROME ? 1 : 8,
-				     stencil_mask ? "1 0" : color == CAIRO_IMAGE_IS_COLOR ? "0 1 0 1 0 1" : "0 1");
-	if (surface->use_string_datasource) {
+				     decode);
+	if (surface->paint_proc) {
 	    _cairo_output_stream_printf (surface->stream,
-					 "  /DataSource {\n"
-					 "    CairoImageData CairoImageDataIndex get\n"
-					 "    /CairoImageDataIndex CairoImageDataIndex 1 add def\n"
-					 "    CairoImageDataIndex CairoImageData length 1 sub gt\n"
-					 "     { /CairoImageDataIndex 0 def } if\n"
-					 "  } /ASCII85Decode filter /%s filter def\n",
+					 "  /DataSource { cairo_data_source } /%s filter\n",
 					 compress_filter);
 	} else {
 	    _cairo_output_stream_printf (surface->stream,
-					 "  /DataSource cairo_ascii85_file /%s filter def\n",
+					 "  /DataSource cairo_ascii85_file /%s filter\n",
 					 compress_filter);
 	}
 
 	_cairo_output_stream_printf (surface->stream,
-				     "  /ImageMatrix [ 1 0 0 -1 0 %d ] def\n"
-				     "end\n"
+				     "  /ImageMatrix [ %d 0 0 %d 0 %d ]\n"
+				     ">>\n"
 				     "%s%s\n",
+				     ps_image->width,
+				     -ps_image->height,
 				     ps_image->height,
-				     surface->use_string_datasource ? "" : "cairo_",
-				     stencil_mask ? "imagemask" : "image");
+				     surface->paint_proc ? "" : "cairo_",
+				     params->stencil_mask ? "imagemask" : "image");
     }
 
-    if (!surface->use_string_datasource) {
+    if (!surface->paint_proc) {
 	/* Emit the image data as a base85-encoded string which will
 	 * be used as the data source for the image operator. */
 	status = _cairo_ps_surface_emit_base85_string (surface,
@@ -2810,14 +2936,15 @@
     if (image != image_surf)
 	cairo_surface_destroy (&image->base);
 
+    _cairo_surface_release_source_image (params->src_surface, image_surf, image_extra);
+
     return status;
 }
 
-static cairo_status_t
-_cairo_ps_surface_emit_jpeg_image (cairo_ps_surface_t    *surface,
-				   cairo_surface_t	 *source,
-				   int                    width,
-				   int                    height)
+static cairo_int_status_t
+_cairo_ps_surface_emit_jpeg_image (cairo_ps_surface_t          *surface,
+				   cairo_emit_surface_mode_t    mode,
+				   cairo_emit_surface_params_t *params)
 {
     cairo_status_t status;
     const unsigned char *mime_data;
@@ -2826,10 +2953,11 @@
     const char *colorspace;
     const char *decode;
 
-    cairo_surface_get_mime_data (source, CAIRO_MIME_TYPE_JPEG,
+    if (unlikely (params->src_surface->status))
+	return params->src_surface->status;
+
+    cairo_surface_get_mime_data (params->src_surface, CAIRO_MIME_TYPE_JPEG,
 				 &mime_data, &mime_data_length);
-    if (unlikely (source->status))
-	return source->status;
     if (mime_data == NULL)
 	return CAIRO_INT_STATUS_UNSUPPORTED;
 
@@ -2854,11 +2982,18 @@
 	    return CAIRO_INT_STATUS_UNSUPPORTED;
     }
 
-    if (surface->use_string_datasource) {
+    /* At this point we know emitting jpeg will succeed. */
+    if (mode == CAIRO_EMIT_SURFACE_ANALYZE) {
+	params->is_image = TRUE;
+	params->approx_size = mime_data_length;
+	return CAIRO_STATUS_SUCCESS;
+    }
+
+    if (surface->paint_proc) {
 	/* Emit the image data as a base85-encoded string which will
 	 * be used as the data source for the image operator later. */
 	_cairo_output_stream_printf (surface->stream,
-				     "/CairoImageData [\n");
+				     "/CairoData [\n");
 
 	status = _cairo_ps_surface_emit_base85_string (surface,
 						       mime_data,
@@ -2871,7 +3006,7 @@
 	_cairo_output_stream_printf (surface->stream,
 				     "] def\n");
 	_cairo_output_stream_printf (surface->stream,
-				     "/CairoImageDataIndex 0 def\n");
+				     "/CairoDataIndex 0 def\n");
     } else {
 	_cairo_output_stream_printf (surface->stream,
 				     "/cairo_ascii85_file currentfile /ASCII85Decode filter def\n");
@@ -2879,39 +3014,38 @@
 
     _cairo_output_stream_printf (surface->stream,
 				 "%s setcolorspace\n"
-				 "8 dict dup begin\n"
-				 "  /ImageType 1 def\n"
-				 "  /Width %d def\n"
-				 "  /Height %d def\n"
-				 "  /BitsPerComponent %d def\n"
-				 "  /Decode [ %s ] def\n",
+				 "<<\n"
+				 "  /ImageType 1\n"
+				 "  /Width %d\n"
+				 "  /Height %d\n"
+				 "  /BitsPerComponent %d\n"
+				 "  /Interpolate %s\n"
+				 "  /Decode [ %s ]\n",
 				 colorspace,
 				 info.width,
 				 info.height,
 				 info.bits_per_component,
+				 get_interpolate (params->filter),
                                  decode);
 
-    if (surface->use_string_datasource) {
+    if (surface->paint_proc) {
 	_cairo_output_stream_printf (surface->stream,
-				     "  /DataSource {\n"
-				     "    CairoImageData CairoImageDataIndex get\n"
-				     "    /CairoImageDataIndex CairoImageDataIndex 1 add def\n"
-				     "    CairoImageDataIndex CairoImageData length 1 sub gt\n"
-				     "     { /CairoImageDataIndex 0 def } if\n"
-				     "  } /ASCII85Decode filter /DCTDecode filter def\n");
+				     "  /DataSource { cairo_data_source } /DCTDecode filter\n");
     } else {
 	_cairo_output_stream_printf (surface->stream,
-				     "  /DataSource cairo_ascii85_file /DCTDecode filter def\n");
+				     "  /DataSource cairo_ascii85_file /DCTDecode filter\n");
     }
 
     _cairo_output_stream_printf (surface->stream,
-				 "  /ImageMatrix [ 1 0 0 -1 0 %d ] def\n"
-				 "end\n"
+				 "  /ImageMatrix [ %d 0 0 %d 0 %d ]\n"
+				 ">>\n"
 				 "%simage\n",
+				 info.width,
+				 -info.height,
 				 info.height,
-				 surface->use_string_datasource ? "" : "cairo_");
+				 surface->paint_proc ? "" : "cairo_");
 
-    if (!surface->use_string_datasource) {
+    if (!surface->paint_proc) {
 	/* Emit the image data as a base85-encoded string which will
 	 * be used as the data source for the image operator. */
 	status = _cairo_ps_surface_emit_base85_string (surface,
@@ -2924,117 +3058,309 @@
     return status;
 }
 
-static cairo_status_t
-_cairo_ps_surface_emit_recording_surface (cairo_ps_surface_t *surface,
-					  cairo_surface_t    *recording_surface)
+static cairo_int_status_t
+_cairo_ps_surface_emit_ccitt_image (cairo_ps_surface_t          *surface,
+				    cairo_emit_surface_mode_t    mode,
+				    cairo_emit_surface_params_t *params)
 {
-    double old_width, old_height;
-    cairo_matrix_t old_cairo_to_ps;
-    cairo_content_t old_content;
-    cairo_rectangle_int_t old_page_bbox;
-    cairo_surface_t *free_me = NULL;
-    cairo_surface_clipper_t old_clipper;
-    cairo_box_t bbox;
-    cairo_int_status_t status;
+    cairo_status_t status;
+    const unsigned char *ccitt_data;
+    unsigned long ccitt_data_len;
+    const unsigned char *ccitt_params_data;
+    unsigned long ccitt_params_data_len;
+    char *ccitt_params_string;
+    cairo_ccitt_params_t ccitt_params;
 
-    old_content = surface->content;
-    old_width = surface->width;
-    old_height = surface->height;
-    old_page_bbox = surface->page_bbox;
-    old_cairo_to_ps = surface->cairo_to_ps;
-    old_clipper = surface->clipper;
-    _cairo_surface_clipper_init (&surface->clipper,
-				 _cairo_ps_surface_clipper_intersect_clip_path);
+    if (unlikely (params->src_surface->status))
+	return params->src_surface->status;
 
-    if (_cairo_surface_is_snapshot (recording_surface))
-	free_me = recording_surface = _cairo_surface_snapshot_get_target (recording_surface);
+    cairo_surface_get_mime_data (params->src_surface, CAIRO_MIME_TYPE_CCITT_FAX,
+				 &ccitt_data, &ccitt_data_len);
+    if (ccitt_data == NULL)
+	return CAIRO_INT_STATUS_UNSUPPORTED;
 
-    status =
-	_cairo_recording_surface_get_bbox ((cairo_recording_surface_t *) recording_surface,
-					   &bbox,
-					   NULL);
-    if (unlikely (status))
-	goto err;
+    cairo_surface_get_mime_data (params->src_surface, CAIRO_MIME_TYPE_CCITT_FAX_PARAMS,
+				 &ccitt_params_data, &ccitt_params_data_len);
+    if (ccitt_params_data == NULL)
+	return CAIRO_INT_STATUS_UNSUPPORTED;
 
-#if DEBUG_PS
-    _cairo_output_stream_printf (surface->stream,
-				 "%% _cairo_ps_surface_emit_recording_surface (%f, %f), (%f, %f)\n",
-				 _cairo_fixed_to_double (bbox.p1.x),
-				 _cairo_fixed_to_double (bbox.p1.y),
-				 _cairo_fixed_to_double (bbox.p2.x),
-				 _cairo_fixed_to_double (bbox.p2.y));
-#endif
+    /* ensure params_string is null terminated */
+    ccitt_params_string = malloc (ccitt_params_data_len + 1);
+    memcpy (ccitt_params_string, ccitt_params_data, ccitt_params_data_len);
+    ccitt_params_string[ccitt_params_data_len] = 0;
+    status = _cairo_tag_parse_ccitt_params (ccitt_params_string, &ccitt_params);
+    if (unlikely(status))
+	return status;
 
-    surface->width = _cairo_fixed_to_double (bbox.p2.x - bbox.p1.x);
-    surface->height = _cairo_fixed_to_double (bbox.p2.y - bbox.p1.y);
-    _cairo_box_round_to_rectangle (&bbox, &surface->page_bbox);
+    free (ccitt_params_string);
 
-    surface->current_pattern_is_solid_color = FALSE;
-    _cairo_pdf_operators_reset (&surface->pdf_operators);
-    cairo_matrix_init (&surface->cairo_to_ps, 1, 0, 0, -1, 0, surface->height);
-    _cairo_pdf_operators_set_cairo_to_pdf_matrix (&surface->pdf_operators,
-						  &surface->cairo_to_ps);
-    _cairo_output_stream_printf (surface->stream, "  q\n");
+    if (ccitt_params.columns <= 0 || ccitt_params.rows <= 0)
+	return CAIRO_INT_STATUS_UNSUPPORTED;
 
-    if (recording_surface->content == CAIRO_CONTENT_COLOR) {
-	surface->content = CAIRO_CONTENT_COLOR;
+    /* At this point we know emitting ccitt will succeed. */
+    if (mode == CAIRO_EMIT_SURFACE_ANALYZE) {
+	params->is_image = TRUE;
+	params->approx_size = ccitt_data_len;
+	return CAIRO_STATUS_SUCCESS;
+    }
+
+    if (surface->paint_proc) {
+	/* Emit the image data as a base85-encoded string which will
+	 * be used as the data source for the image operator later. */
 	_cairo_output_stream_printf (surface->stream,
-				     "  0 g %d %d %d %d rectfill\n",
-				     surface->page_bbox.x,
-				     surface->page_bbox.y,
-				     surface->page_bbox.width,
-				     surface->page_bbox.height);
+				     "/CairoData [\n");
+
+	status = _cairo_ps_surface_emit_base85_string (surface,
+						       ccitt_data,
+						       ccitt_data_len,
+						       CAIRO_PS_COMPRESS_NONE,
+						       TRUE);
+	if (unlikely (status))
+	    return status;
+
+	_cairo_output_stream_printf (surface->stream,
+				     "] def\n");
+	_cairo_output_stream_printf (surface->stream,
+				     "/CairoDataIndex 0 def\n");
+    } else {
+	_cairo_output_stream_printf (surface->stream,
+				     "/cairo_ascii85_file currentfile /ASCII85Decode filter def\n");
     }
 
-    status = _cairo_recording_surface_replay_region (recording_surface,
-						     NULL,
-						     &surface->base,
-						     CAIRO_RECORDING_REGION_NATIVE);
-    assert (status != CAIRO_INT_STATUS_UNSUPPORTED);
-    if (unlikely (status))
-	goto err;
+    if (!params->stencil_mask) {
+	_cairo_output_stream_printf (surface->stream,
+				     "/DeviceGray setcolorspace\n");
+    }
 
-    status = _cairo_pdf_operators_flush (&surface->pdf_operators);
-    if (unlikely (status))
-	goto err;
+    _cairo_output_stream_printf (surface->stream,
+				 "<<\n"
+				 "  /ImageType 1\n"
+				 "  /Width %d\n"
+				 "  /Height %d\n"
+				 "  /BitsPerComponent 1\n"
+				 "  /Interpolate %s\n"
+				 "  /Decode [ 0 1 ]\n",
+				 ccitt_params.columns,
+				 ccitt_params.rows,
+				 get_interpolate (params->filter));
 
-    _cairo_output_stream_printf (surface->stream, "  Q\n");
+    if (surface->paint_proc) {
+	_cairo_output_stream_printf (surface->stream,
+				     "  /DataSource { cairo_data_source }\n");
+    } else {
+	_cairo_output_stream_printf (surface->stream,
+				     "  /DataSource cairo_ascii85_file\n");
+    }
 
-    _cairo_surface_clipper_reset (&surface->clipper);
-    surface->clipper = old_clipper;
-    surface->content = old_content;
-    surface->width = old_width;
-    surface->height = old_height;
-    surface->page_bbox = old_page_bbox;
-    surface->current_pattern_is_solid_color = FALSE;
-    _cairo_pdf_operators_reset (&surface->pdf_operators);
-    surface->cairo_to_ps = old_cairo_to_ps;
+    _cairo_output_stream_printf (surface->stream,
+				 "  << /Columns %d /Rows %d /K %d\n",
+				 ccitt_params.columns,
+				 ccitt_params.rows,
+				 ccitt_params.k);
 
-    _cairo_pdf_operators_set_cairo_to_pdf_matrix (&surface->pdf_operators,
-						  &surface->cairo_to_ps);
+    if (ccitt_params.end_of_line)
+	_cairo_output_stream_printf (surface->stream, "     /EndOfLine true\n");
 
-err:
-    cairo_surface_destroy (free_me);
+    if (ccitt_params.encoded_byte_align)
+	_cairo_output_stream_printf (surface->stream, "     /EncodedByteAlign true\n");
+
+    if (!ccitt_params.end_of_block)
+	_cairo_output_stream_printf (surface->stream, "     /EndOfBlock false\n");
+
+    if (ccitt_params.black_is_1)
+	_cairo_output_stream_printf (surface->stream, "     /BlackIs1 true\n");
+
+    if (ccitt_params.damaged_rows_before_error > 0) {
+	_cairo_output_stream_printf (surface->stream,
+				     "     /DamagedRowsBeforeError %d\n",
+				     ccitt_params.damaged_rows_before_error);
+    }
+
+    _cairo_output_stream_printf (surface->stream,
+				 "  >> /CCITTFaxDecode filter\n");
+
+    _cairo_output_stream_printf (surface->stream,
+				 "  /ImageMatrix [ %d 0 0 %d 0 %d ]\n"
+				 ">>\n"
+				 "%s%s\n",
+				 ccitt_params.columns,
+				 -ccitt_params.rows,
+				 ccitt_params.rows,
+				 surface->paint_proc ? "" : "cairo_",
+				 params->stencil_mask ? "imagemask" : "image");
+
+    if (!surface->paint_proc) {
+	/* Emit the image data as a base85-encoded string which will
+	 * be used as the data source for the image operator. */
+	status = _cairo_ps_surface_emit_base85_string (surface,
+						       ccitt_data,
+						       ccitt_data_len,
+						       CAIRO_PS_COMPRESS_NONE,
+						       FALSE);
+    }
+
     return status;
 }
 
-static cairo_int_status_t
-_cairo_ps_surface_emit_recording_subsurface (cairo_ps_surface_t *surface,
-					     cairo_surface_t    *recording_surface,
-					     const cairo_rectangle_int_t *extents)
+/* The '|' character is not used in PS (including ASCII85).  We can
+ * speed up the search by first searching for the first char before
+ * comparing strings.
+ */
+#define SUBFILE_FILTER_EOD "|EOD|"
+
+/* Count number of non overlapping occurrences of SUBFILE_FILTER_EOD in data. */
+static int
+count_eod_strings (const unsigned char *data, unsigned long data_len)
 {
+    const unsigned char *p = data;
+    const unsigned char *end;
+    int first_char, len, count;
+    const char *eod_str = SUBFILE_FILTER_EOD;
+
+    first_char = eod_str[0];
+    len = strlen (eod_str);
+    p = data;
+    end = data + data_len - len + 1;
+    count = 0;
+    while (p < end) {
+	p = memchr (p, first_char, end - p);
+	if (!p)
+	    break;
+
+	if (memcmp (p, eod_str, len) == 0) {
+	    count++;
+	    p += len;
+	}
+    }
+
+    return count;
+}
+
+static cairo_status_t
+_cairo_ps_surface_emit_eps (cairo_ps_surface_t          *surface,
+			    cairo_emit_surface_mode_t    mode,
+			    cairo_emit_surface_params_t *params)
+{
+    cairo_status_t status;
+    const unsigned char *eps_data = NULL;
+    unsigned long eps_data_len;
+    const unsigned char *eps_params_string = NULL;
+    unsigned long eps_params_string_len;
+    char *params_string = NULL;
+    cairo_eps_params_t eps_params;
+    cairo_matrix_t mat;
+    double eps_width, eps_height;
+
+    if (unlikely (params->src_surface->status))
+	return params->src_surface->status;
+
+    /* We only embed EPS with level 3 as we may use ReusableStreamDecode and we
+     * don't know what level the EPS file requires. */
+    if (surface->ps_level == CAIRO_PS_LEVEL_2)
+	return CAIRO_INT_STATUS_UNSUPPORTED;
+
+    cairo_surface_get_mime_data (params->src_surface, CAIRO_MIME_TYPE_EPS,
+				 &eps_data, &eps_data_len);
+    if (eps_data == NULL)
+	return CAIRO_INT_STATUS_UNSUPPORTED;
+
+    cairo_surface_get_mime_data (params->src_surface, CAIRO_MIME_TYPE_EPS_PARAMS,
+				 &eps_params_string, &eps_params_string_len);
+    if (eps_params_string == NULL)
+	return CAIRO_INT_STATUS_UNSUPPORTED;
+
+    /* ensure params_string is null terminated */
+    params_string = malloc (eps_params_string_len + 1);
+    memcpy (params_string, eps_params_string, eps_params_string_len);
+    params_string[eps_params_string_len] = 0;
+    status = _cairo_tag_parse_eps_params (params_string, &eps_params);
+    if (unlikely(status))
+	return status;
+
+    /* At this point we know emitting EPS will succeed. */
+    if (mode == CAIRO_EMIT_SURFACE_ANALYZE) {
+	params->is_image = FALSE;
+	params->approx_size = eps_data_len;
+	surface->contains_eps = TRUE;
+
+	/* Find number of occurrences of SUBFILE_FILTER_EOD in the EPS data.
+	 * We will need it before emitting the data if a ReusableStream is used.
+         */
+	params->eod_count = count_eod_strings (eps_data, eps_data_len);
+	return CAIRO_STATUS_SUCCESS;
+    }
+
+    surface->ps_level_used = CAIRO_PS_LEVEL_3;
+    _cairo_output_stream_printf (surface->stream, "cairo_eps_begin\n");
+
+    eps_width = eps_params.bbox.p2.x - eps_params.bbox.p1.x;
+    eps_height = eps_params.bbox.p2.y - eps_params.bbox.p1.y;
+    cairo_matrix_init_translate (&mat,
+				 params->src_surface_extents->x,
+				 params->src_surface_extents->y);
+    cairo_matrix_scale (&mat,
+			params->src_surface_extents->width/eps_width,
+			params->src_surface_extents->height/eps_height);
+    cairo_matrix_scale (&mat, 1, -1);
+    cairo_matrix_translate (&mat, -eps_params.bbox.p1.x, -eps_params.bbox.p2.y);
+
+    if (! _cairo_matrix_is_identity (&mat)) {
+	_cairo_output_stream_printf (surface->stream, "[ ");
+	_cairo_output_stream_print_matrix (surface->stream, &mat);
+	_cairo_output_stream_printf (surface->stream, " ] concat\n");
+    }
+
+    _cairo_output_stream_printf (surface->stream,
+				 "%f %f %f %f rectclip\n",
+				 eps_params.bbox.p1.x,
+				 eps_params.bbox.p1.y,
+				 eps_width,
+				 eps_height);
+
+    _cairo_output_stream_write (surface->stream, eps_data, eps_data_len);
+    _cairo_output_stream_printf (surface->stream, "\ncairo_eps_end\n");
+
+    return CAIRO_STATUS_SUCCESS;
+}
+
+static cairo_status_t
+_cairo_ps_surface_emit_recording_surface (cairo_ps_surface_t          *surface,
+					  cairo_surface_t             *recording_surface,
+					  const cairo_rectangle_int_t *recording_extents,
+					  cairo_bool_t                 subsurface)
+{
     double old_width, old_height;
+    cairo_rectangle_int_t old_surface_extents;
+    cairo_bool_t old_surface_bounded;
     cairo_matrix_t old_cairo_to_ps;
     cairo_content_t old_content;
-    cairo_rectangle_int_t old_page_bbox;
     cairo_surface_clipper_t old_clipper;
+    cairo_int_status_t status;
     cairo_surface_t *free_me = NULL;
-    cairo_int_status_t status;
+    unsigned int id;
+    int i, recording_surf_stack_size;
 
+    /* Prevent infinite recursion if the recording_surface references a recording
+     * currently being emitted */
+    recording_surf_stack_size = _cairo_array_num_elements (&surface->recording_surf_stack);
+    for (i = 0; i < recording_surf_stack_size; i++) {
+	_cairo_array_copy_element (&surface->recording_surf_stack, i, &id);
+	if (id == recording_surface->unique_id)
+	    return CAIRO_STATUS_SUCCESS;
+    }
+    id = recording_surface->unique_id;
+    status = _cairo_array_append (&surface->recording_surf_stack, &id);
+    if (unlikely (status))
+	return status;
+
+    if (_cairo_surface_is_snapshot (recording_surface))
+	free_me = recording_surface = _cairo_surface_snapshot_get_target (recording_surface);
+
     old_content = surface->content;
     old_width = surface->width;
     old_height = surface->height;
-    old_page_bbox = surface->page_bbox;
+    old_surface_extents = surface->surface_extents;
+    old_surface_bounded = surface->surface_bounded;
     old_cairo_to_ps = surface->cairo_to_ps;
     old_clipper = surface->clipper;
     _cairo_surface_clipper_init (&surface->clipper,
@@ -3042,46 +3368,44 @@
 
 #if DEBUG_PS
     _cairo_output_stream_printf (surface->stream,
-				 "%% _cairo_ps_surface_emit_recording_subsurface (%d, %d), (%d, %d)\n",
-				 extents->x, extents->y,
-				 extents->width, extents->height);
+				 "%% _cairo_ps_surface_emit_recording_surface"
+				 " x: %d, y: %d, w: %d, h: %d subsurface: %d\n",
+				 recording_extents->x, recording_extents->y,
+				 recording_extents->width, recording_extents->height,
+				 subsurface);
 #endif
 
-    surface->page_bbox.x = surface->page_bbox.y = 0;
-    surface->page_bbox.width = surface->width  = extents->width;
-    surface->page_bbox.height = surface->height = extents->height;
-
+    surface->width = recording_extents->width;
+    surface->height = recording_extents->height;
+    surface->surface_extents = *recording_extents;
     surface->current_pattern_is_solid_color = FALSE;
     _cairo_pdf_operators_reset (&surface->pdf_operators);
-    cairo_matrix_init (&surface->cairo_to_ps, 1, 0, 0, -1, 0, surface->height);
+    cairo_matrix_init (&surface->cairo_to_ps, 1, 0, 0, 1, 0, 0);
     _cairo_pdf_operators_set_cairo_to_pdf_matrix (&surface->pdf_operators,
 						  &surface->cairo_to_ps);
     _cairo_output_stream_printf (surface->stream, "  q\n");
 
-    if (_cairo_surface_is_snapshot (recording_surface))
-	free_me = recording_surface = _cairo_surface_snapshot_get_target (recording_surface);
-
     if (recording_surface->content == CAIRO_CONTENT_COLOR) {
 	surface->content = CAIRO_CONTENT_COLOR;
 	_cairo_output_stream_printf (surface->stream,
 				     "  0 g %d %d %d %d rectfill\n",
-				     surface->page_bbox.x,
-				     surface->page_bbox.y,
-				     surface->page_bbox.width,
-				     surface->page_bbox.height);
+				     recording_extents->x,
+				     recording_extents->y,
+				     recording_extents->width,
+				     recording_extents->height);
     }
 
     status = _cairo_recording_surface_replay_region (recording_surface,
-						     extents,
+						     subsurface ? recording_extents : NULL,
 						     &surface->base,
 						     CAIRO_RECORDING_REGION_NATIVE);
     assert (status != CAIRO_INT_STATUS_UNSUPPORTED);
     if (unlikely (status))
-	goto err;
+	return status;
 
     status = _cairo_pdf_operators_flush (&surface->pdf_operators);
     if (unlikely (status))
-	goto err;
+	return status;
 
     _cairo_output_stream_printf (surface->stream, "  Q\n");
 
@@ -3090,7 +3414,8 @@
     surface->content = old_content;
     surface->width = old_width;
     surface->height = old_height;
-    surface->page_bbox = old_page_bbox;
+    surface->surface_extents = old_surface_extents;
+    surface->surface_bounded = old_surface_bounded;
     surface->current_pattern_is_solid_color = FALSE;
     _cairo_pdf_operators_reset (&surface->pdf_operators);
     surface->cairo_to_ps = old_cairo_to_ps;
@@ -3097,9 +3422,10 @@
 
     _cairo_pdf_operators_set_cairo_to_pdf_matrix (&surface->pdf_operators,
 						  &surface->cairo_to_ps);
+    cairo_surface_destroy (free_me);
 
-err:
-    cairo_surface_destroy (free_me);
+    _cairo_array_truncate (&surface->recording_surf_stack, recording_surf_stack_size);
+
     return status;
 }
 
@@ -3145,45 +3471,352 @@
 				     red, green, blue);
 }
 
-static cairo_status_t
-_cairo_ps_surface_emit_surface (cairo_ps_surface_t      *surface,
-				cairo_pattern_t         *source_pattern,
-				cairo_surface_t         *source_surface,
-				cairo_operator_t	 op,
-				int                      width,
-				int                      height,
-				cairo_bool_t             stencil_mask)
+/*
+ * PS Forms are used for sources that have CAIRO_MIME_TYPE_UNIQUE_ID. They will be
+ * emitted once in the PS header and can be rendered with the 'execform' operator.
+ *
+ * This function tries adding the source the form hash table. If the source does not
+ * have CAIRO_MIME_TYPE_UNIQUE_ID, CAIRO_INT_STATUS_UNSUPPORTED is returned.
+
+ * @source: [in] the source for the form
+ * @params: [in] source parameters
+ * @test: [in] if TRUE, test if form will be used (excludes size check)
+ * @ps_form [out] the new or exisiting entry int the hash table.
+ *                image or recording.
+ */
+static cairo_int_status_t
+_cairo_ps_surface_use_form (cairo_ps_surface_t           *surface,
+			    cairo_emit_surface_params_t  *params,
+			    cairo_bool_t                  test,
+			    cairo_ps_form_t             **ps_form)
 {
+    cairo_ps_form_t source_key;
+    cairo_ps_form_t *source_entry;
+    unsigned char *unique_id = NULL;
+    unsigned long unique_id_length = 0;
+    cairo_status_t status;
+    long max_size;
+
+    if (params->op != CAIRO_OPERATOR_OVER || params->stencil_mask)
+	return CAIRO_INT_STATUS_UNSUPPORTED;
+
+    if (params->src_surface->backend->type == CAIRO_SURFACE_TYPE_SUBSURFACE)
+	return CAIRO_INT_STATUS_UNSUPPORTED;
+
+    cairo_surface_get_mime_data (params->src_surface, CAIRO_MIME_TYPE_UNIQUE_ID,
+				 (const unsigned char **) &source_key.unique_id,
+				 &source_key.unique_id_length);
+    if (source_key.unique_id == NULL || source_key.unique_id_length == 0)
+	return CAIRO_INT_STATUS_UNSUPPORTED;
+
+    if (test)
+	return CAIRO_STATUS_SUCCESS;
+
+    source_key.filter = params->filter;
+    _cairo_ps_form_init_key (&source_key);
+    source_entry = _cairo_hash_table_lookup (surface->forms, &source_key.base);
+    if (source_entry) {
+	_cairo_rectangle_union (&source_entry->required_extents, params->src_op_extents);
+	*ps_form = source_entry;
+	return CAIRO_STATUS_SUCCESS;
+    }
+
+    if (surface->ps_level == CAIRO_PS_LEVEL_3)
+	max_size = MAX_L3_FORM_DATA;
+    else
+	max_size = MAX_L3_FORM_DATA;
+
+    /* Don't add any more Forms if we exceed the form memory limit */
+    if (surface->total_form_size + params->approx_size > max_size)
+	return CAIRO_INT_STATUS_UNSUPPORTED;
+
+    surface->total_form_size += params->approx_size > max_size;
+    unique_id = _cairo_malloc (source_key.unique_id_length);
+    if (unique_id == NULL)
+	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
+
+    unique_id_length = source_key.unique_id_length;
+    memcpy (unique_id, source_key.unique_id, unique_id_length);
+
+    source_entry = calloc (sizeof (cairo_ps_form_t), 1);
+    if (source_entry == NULL) {
+	status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
+	goto fail;
+    }
+
+    source_entry->unique_id_length = unique_id_length;
+    source_entry->unique_id = unique_id;
+    source_entry->id = surface->num_forms++;
+    source_entry->src_surface = cairo_surface_reference (params->src_surface);
+    source_entry->required_extents = *params->src_op_extents;
+    source_entry->filter = params->filter;
+    source_entry->is_image = params->is_image;
+    _cairo_ps_form_init_key (source_entry);
+    status = _cairo_hash_table_insert (surface->forms, &source_entry->base);
+    if (unlikely(status))
+	goto fail;
+
+    *ps_form = source_entry;
+    return CAIRO_STATUS_SUCCESS;
+
+  fail:
+    free (unique_id);
+    free (source_entry);
+    return status;
+}
+
+static cairo_int_status_t
+_cairo_ps_surface_emit_form (cairo_ps_surface_t          *surface,
+			     cairo_emit_surface_params_t *params,
+			     cairo_bool_t                 test)
+{
+    cairo_ps_form_t *ps_form = NULL;
+    cairo_status_t status;
+
+    status = _cairo_ps_surface_use_form (surface,
+					 params,
+					 test,
+					 &ps_form);
+    if (test || status)
+	return status;
+
+    /* _cairo_ps_form_emit will use Level 3 if permitted by ps_level */
+    if (surface->ps_level == CAIRO_PS_LEVEL_3)
+	surface->ps_level_used = CAIRO_PS_LEVEL_3;
+
+    _cairo_output_stream_printf (surface->stream,
+				 "/cairoform-%d /Form findresource execform\n",
+				 ps_form->id);
+
+    return CAIRO_STATUS_SUCCESS;
+}
+
+/* Emit a surface. This function has three modes.
+ *
+ * CAIRO_EMIT_SURFACE_ANALYZE: This will determine the surface type to
+ * be emitted and approximate size. is_image is set to TRUE if the
+ * emitted surface is an image surface (including mime images). This
+ * is used by the caller to setup the correct CTM. approx_size is set
+ * to the approximate size of the emitted surface and is used as an
+ * input by the emit mode.
+ *
+ * CAIRO_EMIT_SURFACE_EMIT: Emits the surface will be emitted. The
+ * approx_size and the surface unique id values are used to determine
+ * if a Form should be used. If a form is used, the exec form
+ * operation is emitted and the surface is added to the forms hash
+ * table.
+ *
+ * CAIRO_EMIT_SURFACE_EMIT_FORM: Emits the form definition for the surface.
+ *
+ * Usage is:
+ * 1) Setup input params and call with ANALYZE.
+ * 2) Setup CTM for surface and call with EMIT using same params struct.
+ * The EMIT_FORM mode is used when emitting the form definitions.
+ */
+static cairo_int_status_t
+_cairo_ps_surface_emit_surface (cairo_ps_surface_t          *surface,
+				cairo_emit_surface_mode_t    mode,
+				cairo_emit_surface_params_t *params)
+{
     cairo_int_status_t status;
+    cairo_output_stream_t *old_stream = NULL;
+    cairo_bool_t use_form;
 
-    if (source_pattern->type == CAIRO_PATTERN_TYPE_SURFACE &&
-	source_pattern->extend != CAIRO_EXTEND_PAD)
-    {
-	cairo_surface_t *surf = ((cairo_surface_pattern_t *) source_pattern)->surface;
+    /* Try emitting as a form. Returns unsupported if the surface is
+     * deemed unsuitable for a form. */
+    use_form = FALSE;
+    if (mode == CAIRO_EMIT_SURFACE_ANALYZE || mode == CAIRO_EMIT_SURFACE_EMIT) {
+	status = _cairo_ps_surface_emit_form (surface,
+					      params,
+					      mode == CAIRO_EMIT_SURFACE_ANALYZE);
+	use_form = (status == CAIRO_INT_STATUS_SUCCESS);
+	if (status != CAIRO_INT_STATUS_SUCCESS && status != CAIRO_INT_STATUS_UNSUPPORTED)
+	    return status;
 
-	status = _cairo_ps_surface_emit_jpeg_image (surface, surf, width, height);
-	if (status != CAIRO_INT_STATUS_UNSUPPORTED)
+	if (mode == CAIRO_EMIT_SURFACE_EMIT && status == CAIRO_INT_STATUS_SUCCESS)
 	    return status;
     }
 
-    if (source_surface->type == CAIRO_SURFACE_TYPE_RECORDING) {
-	if (source_surface->backend->type == CAIRO_SURFACE_TYPE_SUBSURFACE) {
-	    cairo_surface_subsurface_t *sub = (cairo_surface_subsurface_t *) source_surface;
-	    status = _cairo_ps_surface_emit_recording_subsurface (surface, sub->target, &sub->extents);
+    status = _cairo_ps_surface_emit_eps (surface, mode, params);
+    if (status == CAIRO_INT_STATUS_SUCCESS) {
+	params->is_image = FALSE;
+	goto surface_emitted;
+    }
+    if (status != CAIRO_INT_STATUS_UNSUPPORTED)
+	return status;
+
+    status = _cairo_ps_surface_emit_jpeg_image (surface, mode, params);
+    if (status == CAIRO_INT_STATUS_SUCCESS) {
+	params->is_image = TRUE;
+	goto surface_emitted;
+    }
+    if (status != CAIRO_INT_STATUS_UNSUPPORTED)
+	return status;
+
+    status = _cairo_ps_surface_emit_ccitt_image (surface, mode, params);
+    if (status == CAIRO_INT_STATUS_SUCCESS) {
+	params->is_image = TRUE;
+	goto surface_emitted;
+    }
+    if (status != CAIRO_INT_STATUS_UNSUPPORTED)
+	return status;
+
+    if (mode == CAIRO_EMIT_SURFACE_ANALYZE) {
+	/* Find size of image or recording surface by emitting to a memory stream */
+	status = _cairo_pdf_operators_flush (&surface->pdf_operators);
+	if (unlikely (status))
+	    return status;
+
+	old_stream = surface->stream;
+	surface->stream = _cairo_memory_stream_create ();
+	_cairo_pdf_operators_set_stream (&surface->pdf_operators, surface->stream);
+    }
+
+    if (params->src_surface->type == CAIRO_SURFACE_TYPE_RECORDING) {
+	params->is_image = FALSE;
+	if (params->src_surface->backend->type == CAIRO_SURFACE_TYPE_SUBSURFACE) {
+	    cairo_surface_subsurface_t *sub = (cairo_surface_subsurface_t *) params->src_surface;
+	    status = _cairo_ps_surface_emit_recording_surface (surface,
+							       sub->target,
+							       &sub->extents,
+							       TRUE);
 	} else {
-	    status = _cairo_ps_surface_emit_recording_surface (surface, source_surface);
+	    status = _cairo_ps_surface_emit_recording_surface (surface,
+							       params->src_surface,
+							       params->src_op_extents,
+							       FALSE);
 	}
     } else {
-	cairo_image_surface_t *image = (cairo_image_surface_t *) source_surface;
+	params->is_image = TRUE;
+	status = _cairo_ps_surface_emit_image (surface, mode, params);
+    }
 
-	status = _cairo_ps_surface_emit_image (surface, image,
-					       op, source_pattern->filter, stencil_mask);
+    if (mode == CAIRO_EMIT_SURFACE_ANALYZE) {
+	unsigned char *data;
+	unsigned long length;
+
+	status = _cairo_pdf_operators_flush (&surface->pdf_operators);
+	if (unlikely (status))
+	    return status;
+
+	status = _cairo_memory_stream_destroy (surface->stream, &data, &length);
+	free (data);
+	if (unlikely (status))
+	    return status;
+
+	params->approx_size = length;
+	surface->stream = old_stream;
+	_cairo_pdf_operators_set_stream (&surface->pdf_operators,
+					 surface->stream);
     }
 
+  surface_emitted:
+
     return status;
 }
 
+static void
+_cairo_ps_form_emit (void *entry, void *closure)
+{
+    cairo_ps_form_t *form = entry;
+    cairo_ps_surface_t *surface = closure;
+    cairo_emit_surface_params_t params;
+    cairo_int_status_t status;
+    cairo_output_stream_t *old_stream;
 
+    params.src_surface = form->src_surface;
+    params.op = CAIRO_OPERATOR_OVER;
+    params.src_op_extents = &form->required_extents;
+    params.filter = form->filter;
+    params.stencil_mask = FALSE;
+    params.is_image = form->is_image;
+    params.approx_size = 0;
+
+    _cairo_output_stream_printf (surface->final_stream,
+				 "%%%%BeginResource: form cairoform-%d\n",
+				 form->id);
+
+    _cairo_output_stream_printf (surface->final_stream,
+				 "/cairo_paint_form-%d",
+				 form->id);
+    if (surface->ps_level == CAIRO_PS_LEVEL_3) {
+	surface->paint_proc = FALSE;
+	_cairo_output_stream_printf (surface->final_stream,
+				     "\n"
+				     "currentfile\n"
+				     "<< /Filter /SubFileDecode\n"
+				     "   /DecodeParms << /EODString (%s) /EODCount 0 >>\n"
+				     ">> /ReusableStreamDecode filter\n",
+				     SUBFILE_FILTER_EOD);
+    } else {
+	surface->paint_proc = TRUE;
+	_cairo_output_stream_printf (surface->final_stream,
+				     " {\n");
+    }
+    _cairo_output_stream_printf (surface->final_stream,
+				 "5 dict begin\n");
+
+    old_stream = surface->stream;
+    surface->stream = surface->final_stream;
+    _cairo_pdf_operators_set_stream (&surface->pdf_operators, surface->stream);
+    status = _cairo_ps_surface_emit_surface (surface,
+					     CAIRO_EMIT_SURFACE_EMIT_FORM,
+					     &params);
+    status = _cairo_pdf_operators_flush (&surface->pdf_operators);
+    surface->stream = old_stream;
+    _cairo_pdf_operators_set_stream (&surface->pdf_operators, surface->stream);
+
+    _cairo_output_stream_printf (surface->final_stream,
+				 "end\n");
+    if (surface->ps_level == CAIRO_PS_LEVEL_3) {
+	_cairo_output_stream_printf (surface->final_stream,
+				     "%s\n"
+				     "def\n",
+				     SUBFILE_FILTER_EOD);
+    } else {
+	_cairo_output_stream_printf (surface->final_stream,
+				     "} bind def\n");
+    }
+
+    _cairo_output_stream_printf (surface->final_stream,
+				 "\n"
+				 "/cairoform-%d\n"
+				 "<<\n"
+				 "  /FormType 1\n",
+				 form->id);
+
+    if (form->is_image) {
+	_cairo_output_stream_printf (surface->final_stream,
+				     "  /BBox [ 0 0 1 1 ]\n");
+    } else {
+	_cairo_output_stream_printf (surface->final_stream,
+				     "  /BBox [ %d %d %d %d ]\n",
+				     form->required_extents.x,
+				     form->required_extents.y,
+				     form->required_extents.x + form->required_extents.width,
+				     form->required_extents.y + form->required_extents.height);
+    }
+
+    _cairo_output_stream_printf (surface->final_stream,
+				 "  /Matrix [ 1 0 0 1 0 0 ]\n"
+				 "  /PaintProc { pop cairo_paint_form-%d",
+				 form->id);
+
+    if (surface->ps_level == CAIRO_PS_LEVEL_3) {
+	_cairo_output_stream_printf (surface->final_stream,
+				     " dup 0 setfileposition cvx exec");
+    }
+    _cairo_output_stream_printf (surface->final_stream,
+				 " } bind\n"
+				 ">>\n"
+				 "/Form defineresource pop\n");
+
+    _cairo_output_stream_printf (surface->final_stream,
+				 "%%%%EndResource\n");
+    if (status)
+	surface->base.status = status;
+}
+
 static void
 _path_fixed_init_rectangle (cairo_path_fixed_t *path,
 			    cairo_rectangle_int_t *rect)
@@ -3215,19 +3848,21 @@
 
 static cairo_status_t
 _cairo_ps_surface_paint_surface (cairo_ps_surface_t     *surface,
-				 cairo_pattern_t        *pattern,
+				 const cairo_pattern_t  *pattern,
 				 cairo_rectangle_int_t  *extents,
 				 cairo_operator_t	 op,
 				 cairo_bool_t            stencil_mask)
 {
+    cairo_rectangle_int_t src_surface_extents;
+    cairo_bool_t src_surface_bounded;
+    cairo_rectangle_int_t src_op_extents;
+    cairo_surface_t *source_surface;
+    double x_offset, y_offset;
     cairo_status_t status;
-    int width, height;
     cairo_matrix_t cairo_p2d, ps_p2d;
     cairo_path_fixed_t path;
-    double x_offset, y_offset;
-    cairo_surface_t *source;
+    cairo_emit_surface_params_t params;
     cairo_image_surface_t *image = NULL;
-    void *image_extra;
 
     status = _cairo_pdf_operators_flush (&surface->pdf_operators);
     if (unlikely (status))
@@ -3236,10 +3871,12 @@
     status = _cairo_ps_surface_acquire_source_surface_from_pattern (surface,
 								    pattern,
 								    extents,
-								    &width, &height,
-								    &x_offset, &y_offset,
-								    &source,
-								    &image_extra);
+								    &src_surface_extents,
+								    &src_surface_bounded,
+								    &src_op_extents,
+								    &source_surface,
+								    &x_offset,
+								    &y_offset);
     if (unlikely (status))
 	return status;
 
@@ -3248,16 +3885,18 @@
 	((cairo_surface_pattern_t *)pattern)->surface->type == CAIRO_SURFACE_TYPE_IMAGE) {
 	cairo_image_surface_t *img;
 
-	img = (cairo_image_surface_t *) source;
+	img = (cairo_image_surface_t *) source_surface;
 	status = _cairo_ps_surface_create_padded_image_from_image (surface,
 								   img,
 								   &pattern->matrix,
 								   extents,
-								   &width, &height,
-								   &x_offset, &y_offset,
-								   &image);
+								   &image,
+								   &src_surface_extents);
 	if (unlikely (status))
 	    goto release_source;
+
+	x_offset = src_surface_extents.x;
+	y_offset = src_surface_extents.y;
     }
 
     _path_fixed_init_rectangle (&path, extents);
@@ -3278,8 +3917,8 @@
 				     "%% Fallback Image: x=%f y=%f w=%d h=%d ",
 				     -cairo_p2d.x0/x_scale,
 				     -cairo_p2d.y0/y_scale,
-				     (int)(width/x_scale),
-				     (int)(height/y_scale));
+				     (int)(src_surface_extents.width/x_scale),
+				     (int)(src_surface_extents.height/y_scale));
 	if (x_scale == y_scale) {
 	    _cairo_output_stream_printf (surface->stream,
 					 "res=%fppi ",
@@ -3292,14 +3931,16 @@
 	}
 	_cairo_output_stream_printf (surface->stream,
 				     "size=%ld\n",
-				     (long)width*height*3);
+				     (long)src_surface_extents.width * src_surface_extents.height * 3);
     } else {
 	if (op == CAIRO_OPERATOR_SOURCE) {
 	    _cairo_output_stream_printf (surface->stream,
-					 "%d g 0 0 %f %f rectfill\n",
+					 "%d g %d %d %d %d rectfill\n",
 					 surface->content == CAIRO_CONTENT_COLOR ? 0 : 1,
-					 surface->width,
-					 surface->height);
+					 surface->surface_extents.x,
+					 surface->surface_extents.y,
+					 surface->surface_extents.width,
+					 surface->surface_extents.height);
 	}
     }
 
@@ -3310,9 +3951,27 @@
     ps_p2d = surface->cairo_to_ps;
     cairo_matrix_multiply (&ps_p2d, &cairo_p2d, &ps_p2d);
     cairo_matrix_translate (&ps_p2d, x_offset, y_offset);
-    cairo_matrix_translate (&ps_p2d, 0.0, height);
-    cairo_matrix_scale (&ps_p2d, 1.0, -1.0);
 
+    params.src_surface = image ? &image->base : source_surface;
+    params.op = op;
+    params.src_surface_extents = &src_surface_extents;
+    params.src_surface_bounded = src_surface_bounded;
+    params.src_op_extents = &src_op_extents;
+    params.filter = pattern->filter;
+    params.stencil_mask = stencil_mask;
+    params.is_image = FALSE;
+    params.approx_size = 0;
+
+    status = _cairo_ps_surface_emit_surface (surface, CAIRO_EMIT_SURFACE_ANALYZE, &params);
+    if (unlikely (status))
+	goto release_source;
+
+    if (params.is_image) {
+	cairo_matrix_translate (&ps_p2d, 0.0, src_surface_extents.height);
+	cairo_matrix_scale (&ps_p2d, 1.0, -1.0);
+	cairo_matrix_scale (&ps_p2d, src_surface_extents.width, src_surface_extents.height);
+    }
+
     if (! _cairo_matrix_is_identity (&ps_p2d)) {
 	_cairo_output_stream_printf (surface->stream, "[ ");
 	_cairo_output_stream_print_matrix (surface->stream, &ps_p2d);
@@ -3319,18 +3978,13 @@
 	_cairo_output_stream_printf (surface->stream, " ] concat\n");
     }
 
-    status = _cairo_ps_surface_emit_surface (surface,
-					     pattern,
-					     image ? &image->base : source,
-					     op,
-					     width, height,
-					     stencil_mask);
+    status = _cairo_ps_surface_emit_surface (surface, CAIRO_EMIT_SURFACE_EMIT, &params);
 
   release_source:
     if (image)
 	cairo_surface_destroy (&image->base);
 
-    _cairo_ps_surface_release_source_surface_from_pattern (surface, pattern, source, image_extra);
+    _cairo_ps_surface_release_source_surface_from_pattern (surface, pattern, source_surface);
 
     return status;
 }
@@ -3342,15 +3996,17 @@
 					cairo_operator_t	 op)
 {
     cairo_status_t status;
-    int pattern_width = 0; /* squelch bogus compiler warning */
-    int pattern_height = 0; /* squelch bogus compiler warning */
     double xstep, ystep;
+    cairo_rectangle_int_t pattern_extents;
+    cairo_bool_t bounded;
     cairo_matrix_t cairo_p2d, ps_p2d;
-    cairo_bool_t old_use_string_datasource;
+    cairo_bool_t old_paint_proc;
     double x_offset, y_offset;
-    cairo_surface_t *source;
+    cairo_surface_t *source_surface;
     cairo_image_surface_t *image = NULL;
-    void *image_extra;
+    cairo_rectangle_int_t src_op_extents;
+    cairo_emit_surface_params_t params;
+    cairo_extend_t extend = cairo_pattern_get_extend (pattern);
 
     cairo_p2d = pattern->matrix;
     status = cairo_matrix_invert (&cairo_p2d);
@@ -3360,25 +4016,25 @@
     status = _cairo_ps_surface_acquire_source_surface_from_pattern (surface,
 								    pattern,
 								    extents,
-								    &pattern_width, &pattern_height,
-								    &x_offset, &y_offset,
-								    &source,
-								    &image_extra);
+								    &pattern_extents,
+								    &bounded,
+								    &src_op_extents,
+								    &source_surface,
+								    &x_offset, &y_offset);
     if (unlikely (status))
 	return status;
 
-    if (pattern->extend == CAIRO_EXTEND_PAD) {
+    if (extend == CAIRO_EXTEND_PAD) {
 	cairo_image_surface_t *img;
 
-	assert (source->type == CAIRO_SURFACE_TYPE_IMAGE);
-	img = (cairo_image_surface_t *) source;
+	assert (source_surface->type == CAIRO_SURFACE_TYPE_IMAGE);
+	img = (cairo_image_surface_t *) source_surface;
 	status = _cairo_ps_surface_create_padded_image_from_image (surface,
 								   img,
 								   &pattern->matrix,
 								   extents,
-								   &pattern_width, &pattern_height,
-								   &x_offset, &y_offset,
-								   &image);
+								   &image,
+								   &pattern_extents);
 	if (unlikely (status))
 	    goto release_source;
     }
@@ -3385,7 +4041,13 @@
     if (unlikely (status))
 	goto release_source;
 
-    switch (pattern->extend) {
+    if (!bounded)
+    {
+	extend = CAIRO_EXTEND_NONE;
+	_cairo_rectangle_intersect (&pattern_extents, &src_op_extents);
+    }
+
+    switch (extend) {
     case CAIRO_EXTEND_PAD:
     case CAIRO_EXTEND_NONE:
     {
@@ -3402,7 +4064,8 @@
 	 * repeat visibly.
 	 */
 	double x1 = 0.0, y1 = 0.0;
-	double x2 = surface->width, y2 = surface->height;
+	double x2 = surface->surface_extents.width;
+	double y2 = surface->surface_extents.height;
 	_cairo_matrix_transform_bounding_box (&pattern->matrix,
 					      &x1, &y1, &x2, &y2,
 					      NULL);
@@ -3412,16 +4075,16 @@
 	 * required an answer that's large enough, we don't really
 	 * care if it's not as tight as possible.*/
 	xstep = ystep = ceil ((x2 - x1) + (y2 - y1) +
-			      pattern_width + pattern_height);
+			      pattern_extents.width + pattern_extents.height);
 	break;
     }
     case CAIRO_EXTEND_REPEAT:
-	xstep = pattern_width;
-	ystep = pattern_height;
+	xstep = pattern_extents.width;
+	ystep = pattern_extents.height;
 	break;
     case CAIRO_EXTEND_REFLECT:
-	xstep = pattern_width*2;
-	ystep = pattern_height*2;
+	xstep = pattern_extents.width*2;
+	ystep = pattern_extents.height*2;
 	break;
 	/* All the rest (if any) should have been analyzed away, so these
 	 * cases should be unreachable. */
@@ -3432,27 +4095,49 @@
     }
 
     _cairo_output_stream_printf (surface->stream,
-				 "/CairoPattern {\n");
+				 "/CairoPattern {\n"
+				 "q %d %d %d %d rectclip\n",
+				 pattern_extents.x, pattern_extents.y,
+				 pattern_extents.width, pattern_extents.height);
 
-    old_use_string_datasource = surface->use_string_datasource;
-    surface->use_string_datasource = TRUE;
+    if (extend == CAIRO_EXTEND_REPEAT || extend == CAIRO_EXTEND_REFLECT)
+	src_op_extents = pattern_extents;
+
+    old_paint_proc = surface->paint_proc;
+    surface->paint_proc = TRUE;
+    params.src_surface = image ? &image->base : source_surface;
+    params.op = op;
+    params.src_surface_extents = &pattern_extents;
+    params.src_surface_bounded = bounded;
+    params.src_op_extents = &src_op_extents;
+    params.filter = pattern->filter;
+    params.stencil_mask = FALSE;
+    params.is_image = FALSE;
+    params.approx_size = 0;
+    status = _cairo_ps_surface_emit_surface (surface, CAIRO_EMIT_SURFACE_ANALYZE, &params);
+    if (unlikely (status))
+	goto release_source;
+
+    if (params.is_image) {
+	_cairo_output_stream_printf (surface->stream,
+				     "[ %d 0 0 %d 0 0 ] concat\n",
+				     pattern_extents.width, pattern_extents.height);
+    }
+
     if (op == CAIRO_OPERATOR_SOURCE) {
 	_cairo_output_stream_printf (surface->stream,
-				     "%d g 0 0 %f %f rectfill\n",
+				     "%d g %d %d %f %f rectfill\n",
 				     surface->content == CAIRO_CONTENT_COLOR ? 0 : 1,
+				     pattern_extents.x, pattern_extents.y,
 				     xstep, ystep);
     }
-    status = _cairo_ps_surface_emit_surface (surface,
-					     pattern,
-					     image ? &image->base : source,
-					     op,
-					     pattern_width, pattern_height, FALSE);
+
+    status = _cairo_ps_surface_emit_surface (surface, CAIRO_EMIT_SURFACE_EMIT, &params);
     if (unlikely (status))
 	goto release_source;
 
-    surface->use_string_datasource = old_use_string_datasource;
     _cairo_output_stream_printf (surface->stream,
-				 "} bind def\n");
+				 " Q } bind def\n");
 
     _cairo_output_stream_printf (surface->stream,
 				 "<< /PatternType 1\n"
@@ -3462,20 +4147,43 @@
 				 "   /XStep %f /YStep %f\n",
 				 xstep, ystep);
 
-    if (pattern->extend == CAIRO_EXTEND_REFLECT) {
+    if (extend == CAIRO_EXTEND_REFLECT) {
+	cairo_matrix_t mat;
+
 	_cairo_output_stream_printf (surface->stream,
-				     "   /BBox [0 0 %d %d]\n"
+				     "   /BBox [%d %d %d %d]\n"
 				     "   /PaintProc {\n"
-				     "      pop CairoPattern\n"
-				     "      [-1 0 0  1 %d 0] concat CairoPattern\n"
-				     "      [ 1 0 0 -1 0 %d] concat CairoPattern\n"
-				     "      [-1 0 0  1 %d 0] concat CairoPattern\n"
-				     "      CairoPattern\n"
-				     "   } bind\n",
-				     pattern_width*2, pattern_height*2,
-				     pattern_width*2,
-				     pattern_height*2,
-				     pattern_width*2);
+				     "      pop CairoPattern\n",
+				     pattern_extents.x,
+				     pattern_extents.y,
+				     pattern_extents.x + pattern_extents.width*2,
+				     pattern_extents.y + pattern_extents.height*2);
+
+	cairo_matrix_init_translate (&mat, pattern_extents.x, pattern_extents.y);
+	cairo_matrix_scale (&mat, -1, 1);
+	cairo_matrix_translate (&mat, -2*pattern_extents.width, 0);
+	cairo_matrix_translate (&mat, -pattern_extents.x, -pattern_extents.y);
+	_cairo_output_stream_printf (surface->stream, "      q [");
+	_cairo_output_stream_print_matrix (surface->stream, &mat);
+	_cairo_output_stream_printf (surface->stream, "] concat CairoPattern Q\n");
+
+	cairo_matrix_init_translate (&mat, pattern_extents.x, pattern_extents.y);
+	cairo_matrix_scale (&mat, 1, -1);
+	cairo_matrix_translate (&mat, 0, -2*pattern_extents.height);
+	cairo_matrix_translate (&mat, -pattern_extents.x, -pattern_extents.y);
+	_cairo_output_stream_printf (surface->stream, "      q [");
+	_cairo_output_stream_print_matrix (surface->stream, &mat);
+	_cairo_output_stream_printf (surface->stream, "] concat CairoPattern Q\n");
+
+	cairo_matrix_init_translate (&mat, pattern_extents.x, pattern_extents.y);
+	cairo_matrix_scale (&mat, -1, -1);
+	cairo_matrix_translate (&mat, -2*pattern_extents.width, -2*pattern_extents.height);
+	cairo_matrix_translate (&mat, -pattern_extents.x, -pattern_extents.y);
+	_cairo_output_stream_printf (surface->stream, "      q [");
+	_cairo_output_stream_print_matrix (surface->stream, &mat);
+	_cairo_output_stream_printf (surface->stream, "] concat CairoPattern Q\n");
+
+	_cairo_output_stream_printf (surface->stream, "   } bind\n");
     } else {
 	if (op == CAIRO_OPERATOR_SOURCE) {
 	    _cairo_output_stream_printf (surface->stream,
@@ -3483,8 +4191,11 @@
 					 xstep, ystep);
 	} else {
 	    _cairo_output_stream_printf (surface->stream,
-					 "   /BBox [0 0 %d %d]\n",
-					 pattern_width, pattern_height);
+					 "   /BBox [%d %d %d %d]\n",
+					 pattern_extents.x,
+					 pattern_extents.y,
+					 pattern_extents.x + pattern_extents.width,
+					 pattern_extents.y + pattern_extents.height);
 	}
 	_cairo_output_stream_printf (surface->stream,
 				     "   /PaintProc { pop CairoPattern }\n");
@@ -3499,11 +4210,13 @@
     assert (status == CAIRO_STATUS_SUCCESS);
 
     cairo_matrix_init_identity (&ps_p2d);
-    cairo_matrix_translate (&ps_p2d, 0.0, surface->height);
-    cairo_matrix_scale (&ps_p2d, 1.0, -1.0);
     cairo_matrix_multiply (&ps_p2d, &cairo_p2d, &ps_p2d);
-    cairo_matrix_translate (&ps_p2d, 0.0, pattern_height);
-    cairo_matrix_scale (&ps_p2d, 1.0, -1.0);
+    cairo_matrix_translate (&ps_p2d, x_offset, y_offset);
+    if (((cairo_surface_pattern_t *)pattern)->surface->type != CAIRO_SURFACE_TYPE_RECORDING)
+    {
+	cairo_matrix_translate (&ps_p2d, 0.0, pattern_extents.height);
+	cairo_matrix_scale (&ps_p2d, 1.0, -1.0);
+    }
 
     _cairo_output_stream_printf (surface->stream, "[ ");
     _cairo_output_stream_print_matrix (surface->stream, &ps_p2d);
@@ -3511,11 +4224,13 @@
 				 " ]\n"
 				 "makepattern setpattern\n");
 
+    surface->paint_proc = old_paint_proc;
+
   release_source:
     if (image)
 	cairo_surface_destroy (&image->base);
 
-    _cairo_ps_surface_release_source_surface_from_pattern (surface, pattern, source, image_extra);
+    _cairo_ps_surface_release_source_surface_from_pattern (surface, pattern, source_surface);
 
     return status;
 }
@@ -4098,7 +4813,7 @@
     case CAIRO_PATTERN_TYPE_SURFACE:
     case CAIRO_PATTERN_TYPE_RASTER_SOURCE:
        return _cairo_ps_surface_paint_surface (surface,
-                                               (cairo_pattern_t *)source,
+                                               source,
                                                extents,
                                                op,
 					       stencil_mask);
@@ -4107,8 +4822,8 @@
     case CAIRO_PATTERN_TYPE_RADIAL:
     case CAIRO_PATTERN_TYPE_MESH:
 	return _cairo_ps_surface_paint_gradient (surface,
-						  source,
-						  extents);
+						 source,
+						 extents);
 
     case CAIRO_PATTERN_TYPE_SOLID:
     default:
@@ -4146,17 +4861,10 @@
 {
     cairo_ps_surface_t *surface = abstract_surface;
 
-    rectangle->x = 0;
-    rectangle->y = 0;
+    if (surface->surface_bounded)
+	*rectangle = surface->surface_extents;
 
-    /* XXX: The conversion to integers here is pretty bogus, (not to
-     * mention the aribitray limitation of width to a short(!). We
-     * may need to come up with a better interface for get_extents.
-     */
-    rectangle->width  = ceil (surface->width);
-    rectangle->height = ceil (surface->height);
-
-    return TRUE;
+    return surface->surface_bounded;
 }
 
 static void
@@ -4240,8 +4948,11 @@
 	if (unlikely (status))
 	    goto cleanup_composite;
 
-	_cairo_output_stream_printf (stream, "0 0 %f %f rectfill\n",
-				     surface->width, surface->height);
+	_cairo_output_stream_printf (stream, "%d %d %d %d rectfill\n",
+				     surface->surface_extents.x,
+				     surface->surface_extents.y,
+				     surface->surface_extents.width,
+				     surface->surface_extents.height);
     }
 
 cleanup_composite:
@@ -4536,7 +5247,7 @@
     return _cairo_ps_supported_mime_types;
 }
 
-static void
+static cairo_int_status_t
 _cairo_ps_surface_set_paginated_mode (void			*abstract_surface,
 				      cairo_paginated_mode_t	 paginated_mode)
 {
@@ -4545,35 +5256,58 @@
 
     surface->paginated_mode = paginated_mode;
 
-    if (surface->clipper.clip != NULL) {
-	status = _cairo_pdf_operators_flush (&surface->pdf_operators);
+    if (paginated_mode == CAIRO_PAGINATED_MODE_RENDER) {
+	surface->surface_extents.x = 0;
+	surface->surface_extents.y = 0;
+	surface->surface_extents.width  = ceil (surface->width);
+	surface->surface_extents.height = ceil (surface->height);
 
-	_cairo_output_stream_printf (surface->stream, "Q q\n");
-	_cairo_surface_clipper_reset (&surface->clipper);
+	if (surface->clipper.clip != NULL)
+	{
+	    status = _cairo_pdf_operators_flush (&surface->pdf_operators);
+
+	    _cairo_output_stream_printf (surface->stream, "Q q\n");
+	    _cairo_surface_clipper_reset (&surface->clipper);
+	}
     }
+
+    return CAIRO_STATUS_SUCCESS;
 }
 
 static cairo_int_status_t
 _cairo_ps_surface_set_bounding_box (void		*abstract_surface,
-				    cairo_box_t		*bbox)
+				    cairo_box_t		*analysis_bbox)
 {
     cairo_ps_surface_t *surface = abstract_surface;
     int i, num_comments;
     char **comments;
-    int x1, y1, x2, y2;
     cairo_bool_t has_page_media, has_page_bbox;
     const char *page_media;
+    cairo_rectangle_int_t page_bbox;
+    cairo_point_int_t bbox_p1, bbox_p2; /* in PS coordinates */
 
-    x1 = floor (_cairo_fixed_to_double (bbox->p1.x));
-    y1 = floor (surface->height - _cairo_fixed_to_double (bbox->p2.y));
-    x2 = ceil (_cairo_fixed_to_double (bbox->p2.x));
-    y2 = ceil (surface->height - _cairo_fixed_to_double (bbox->p1.y));
+    _cairo_box_round_to_rectangle (analysis_bbox, &page_bbox);
 
-    surface->page_bbox.x = x1;
-    surface->page_bbox.y = y1;
-    surface->page_bbox.width  = x2 - x1;
-    surface->page_bbox.height = y2 - y1;
+    /* convert to PS coordinates */
+    bbox_p1.x = page_bbox.x;
+    bbox_p1.y = ceil(surface->height) - (page_bbox.y + page_bbox.height);
+    bbox_p2.x = page_bbox.x + page_bbox.width;
+    bbox_p2.y = ceil(surface->height) - page_bbox.y;
 
+    if (surface->num_pages == 1) {
+	surface->document_bbox_p1 = bbox_p1;
+	surface->document_bbox_p2 = bbox_p2;
+    } else {
+	if (bbox_p1.x < surface->document_bbox_p1.x)
+	    surface->document_bbox_p1.x = bbox_p1.x;
+	if (bbox_p1.y < surface->document_bbox_p1.y)
+	    surface->document_bbox_p1.y = bbox_p1.y;
+	if (bbox_p2.x < surface->document_bbox_p2.x)
+	    surface->document_bbox_p2.x = bbox_p2.x;
+	if (bbox_p2.y < surface->document_bbox_p2.y)
+	    surface->document_bbox_p2.y = bbox_p2.y;
+    }
+
     _cairo_output_stream_printf (surface->stream,
 				 "%%%%Page: %d %d\n",
 				 surface->num_pages,
@@ -4613,7 +5347,10 @@
     if (!has_page_bbox) {
 	_cairo_output_stream_printf (surface->stream,
 				     "%%%%PageBoundingBox: %d %d %d %d\n",
-				     x1, y1, x2, y2);
+				     bbox_p1.x,
+				     bbox_p1.y,
+				     bbox_p2.x,
+				     bbox_p2.y);
     }
 
     if (!surface->eps) {
@@ -4625,27 +5362,14 @@
 
     _cairo_output_stream_printf (surface->stream,
                                  "%%%%EndPageSetup\n"
-				 "q %d %d %d %d rectclip q\n",
-				 surface->page_bbox.x,
-				 surface->page_bbox.y,
-				 surface->page_bbox.width,
-				 surface->page_bbox.height);
+				 "q %d %d %d %d rectclip\n"
+                                 "1 0 0 -1 0 %f cm q\n",
+				 bbox_p1.x,
+				 bbox_p1.y,
+				 bbox_p2.x - bbox_p1.x,
+				 bbox_p2.y - bbox_p1.y,
+				 ceil(surface->height));
 
-    if (surface->num_pages == 1) {
-	surface->bbox_x1 = x1;
-	surface->bbox_y1 = y1;
-	surface->bbox_x2 = x2;
-	surface->bbox_y2 = y2;
-    } else {
-	if (x1 < surface->bbox_x1)
-	    surface->bbox_x1 = x1;
-	if (y1 < surface->bbox_y1)
-	    surface->bbox_y1 = y1;
-	if (x2 > surface->bbox_x2)
-	    surface->bbox_x2 = x2;
-	if (y2 > surface->bbox_y2)
-	    surface->bbox_y2 = y2;
-    }
     surface->current_pattern_is_solid_color = FALSE;
     _cairo_pdf_operators_reset (&surface->pdf_operators);
 

Modified: trunk/Build/source/libs/cairo/cairo-src/src/cairo-qt-surface.cpp
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/src/cairo-qt-surface.cpp	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/src/cairo-qt-surface.cpp	2018-10-20 03:19:36 UTC (rev 48952)
@@ -631,7 +631,7 @@
 	return _cairo_surface_create_in_error (CAIRO_STATUS_NO_MEMORY);
     }
 
-    surface = (struct _qimage_surface *) malloc (sizeof(*surface));
+    surface = (struct _qimage_surface *) _cairo_malloc (sizeof(*surface));
     if (unlikely (surface == NULL)) {
 	pixman_image_unref (pixman_image);
 	delete qimg;
@@ -1216,7 +1216,7 @@
 
 	cairo_clip_t clip, old_clip = qs->clipper.clip;
 
-	_cairo_clip_init_copy (&clip, &qs->clipper.clip);
+	qs->clipper.clip = _cairo_clip_copy (&clip);
 	status = (cairo_int_status_t) _cairo_clip_clip (&clip,
 							path,
 							fill_rule,
@@ -1530,7 +1530,7 @@
 {
     cairo_qt_surface_t *qs;
 
-    qs = (cairo_qt_surface_t *) malloc (sizeof(cairo_qt_surface_t));
+    qs = (cairo_qt_surface_t *) _cairo_malloc (sizeof(cairo_qt_surface_t));
     if (qs == NULL)
         return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
 
@@ -1569,7 +1569,7 @@
 {
     cairo_qt_surface_t *qs;
 
-    qs = (cairo_qt_surface_t *) malloc (sizeof(cairo_qt_surface_t));
+    qs = (cairo_qt_surface_t *) _cairo_malloc (sizeof(cairo_qt_surface_t));
     if (qs == NULL)
         return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
 
@@ -1618,7 +1618,7 @@
     if ((content & CAIRO_CONTENT_COLOR) == 0)
 	return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_CONTENT));
 
-    qs = (cairo_qt_surface_t *) malloc (sizeof(cairo_qt_surface_t));
+    qs = (cairo_qt_surface_t *) _cairo_malloc (sizeof(cairo_qt_surface_t));
     if (qs == NULL)
         return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
 

Modified: trunk/Build/source/libs/cairo/cairo-src/src/cairo-quartz-font.c
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/src/cairo-quartz-font.c	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/src/cairo-quartz-font.c	2018-10-20 03:19:36 UTC (rev 48952)
@@ -81,6 +81,14 @@
 static void (*CGContextSetAllowsFontSmoothingPtr) (CGContextRef, bool) = NULL;
 static bool (*CGContextGetAllowsFontSmoothingPtr) (CGContextRef) = NULL;
 
+/* Not public in the least bit */
+static CGPathRef (*CGFontGetGlyphPathPtr) (CGFontRef fontRef, CGAffineTransform *textTransform, int unknown, CGGlyph glyph) = NULL;
+
+/* CTFontCreateWithGraphicsFont is not available until 10.5 */
+typedef const struct __CTFontDescriptor *CTFontDescriptorRef;
+static CTFontRef (*CTFontCreateWithGraphicsFontPtr) (CGFontRef, CGFloat, const CGAffineTransform*, CTFontDescriptorRef) = NULL;
+static CGPathRef (*CTFontCreatePathForGlyphPtr) (CTFontRef, CGGlyph, CGAffineTransform *) = NULL;
+
 /* CGFontGetHMetrics isn't public, but the other functions are public/present in 10.5 */
 typedef struct {
     int ascent;
@@ -98,6 +106,10 @@
 static cairo_bool_t _cairo_quartz_font_symbol_lookup_done = FALSE;
 static cairo_bool_t _cairo_quartz_font_symbols_present = FALSE;
 
+/* Defined in 10.11 */
+#define CGGLYPH_MAX ((CGGlyph) 0xFFFE) /* kCGFontIndexMax */
+#define CGGLYPH_INVALID ((CGGlyph) 0xFFFF) /* kCGFontIndexInvalid */
+
 static void
 quartz_font_ensure_symbols(void)
 {
@@ -125,6 +137,11 @@
     CGFontGetUnitsPerEmPtr = dlsym(RTLD_DEFAULT, "CGFontGetUnitsPerEm");
     CGFontGetGlyphAdvancesPtr = dlsym(RTLD_DEFAULT, "CGFontGetGlyphAdvances");
 
+    CTFontCreateWithGraphicsFontPtr = dlsym(RTLD_DEFAULT, "CTFontCreateWithGraphicsFont");
+    CTFontCreatePathForGlyphPtr = dlsym(RTLD_DEFAULT, "CTFontCreatePathForGlyph");
+    if (!CTFontCreateWithGraphicsFontPtr || !CTFontCreatePathForGlyphPtr)
+	CGFontGetGlyphPathPtr = dlsym(RTLD_DEFAULT, "CGFontGetGlyphPath");
+
     CGFontGetHMetricsPtr = dlsym(RTLD_DEFAULT, "CGFontGetHMetrics");
     CGFontGetAscentPtr = dlsym(RTLD_DEFAULT, "CGFontGetAscent");
     CGFontGetDescentPtr = dlsym(RTLD_DEFAULT, "CGFontGetDescent");
@@ -140,6 +157,7 @@
 	CGFontGetGlyphsForUnicharsPtr &&
 	CGFontGetUnitsPerEmPtr &&
 	CGFontGetGlyphAdvancesPtr &&
+	((CTFontCreateWithGraphicsFontPtr && CTFontCreatePathForGlyphPtr) || CGFontGetGlyphPathPtr) &&
 	(CGFontGetHMetricsPtr || (CGFontGetAscentPtr && CGFontGetDescentPtr && CGFontGetLeadingPtr)))
 	_cairo_quartz_font_symbols_present = TRUE;
 
@@ -178,7 +196,7 @@
 	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
     family = toy_face->family;
-    full_name = malloc (strlen (family) + 64); // give us a bit of room to tack on Bold, Oblique, etc.
+    full_name = _cairo_malloc (strlen (family) + 64); // give us a bit of room to tack on Bold, Oblique, etc.
     /* handle CSS-ish faces */
     if (!strcmp(family, "serif") || !strcmp(family, "Times Roman"))
 	family = "Times";
@@ -265,7 +283,7 @@
     if (!_cairo_quartz_font_symbols_present)
 	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
-    font = malloc(sizeof(cairo_quartz_scaled_font_t));
+    font = _cairo_malloc (sizeof(cairo_quartz_scaled_font_t));
     if (font == NULL)
 	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
@@ -357,7 +375,7 @@
 
     quartz_font_ensure_symbols();
 
-    font_face = malloc (sizeof (cairo_quartz_font_face_t));
+    font_face = _cairo_malloc (sizeof (cairo_quartz_font_face_t));
     if (!font_face) {
 	cairo_status_t ignore_status;
 	ignore_status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
@@ -389,14 +407,10 @@
 {
 }
 
-#define INVALID_GLYPH 0x00
-
 static inline CGGlyph
 _cairo_quartz_scaled_glyph_index (cairo_scaled_glyph_t *scaled_glyph) {
     unsigned long index = _cairo_scaled_glyph_index (scaled_glyph);
-    if (index > 0xffff)
-	return INVALID_GLYPH;
-    return (CGGlyph) index;
+    return index <= CGGLYPH_MAX ? index : CGGLYPH_INVALID;
 }
 
 static cairo_int_status_t
@@ -413,7 +427,7 @@
     double emscale = CGFontGetUnitsPerEmPtr (font_face->cgFont);
     double xmin, ymin, xmax, ymax;
 
-    if (glyph == INVALID_GLYPH)
+    if (unlikely (glyph == CGGLYPH_INVALID))
 	goto FAIL;
 
     if (!CGFontGetGlyphAdvancesPtr (font_face->cgFont, &glyph, 1, &advance) ||
@@ -545,10 +559,9 @@
     CGGlyph glyph = _cairo_quartz_scaled_glyph_index (scaled_glyph);
     CGAffineTransform textMatrix;
     CGPathRef glyphPath;
-    CTFontRef ctFont;
     cairo_path_fixed_t *path;
 
-    if (glyph == INVALID_GLYPH) {
+    if (unlikely (glyph == CGGLYPH_INVALID)) {
 	_cairo_scaled_glyph_set_path (scaled_glyph, &font->base, _cairo_path_fixed_create());
 	return CAIRO_STATUS_SUCCESS;
     }
@@ -560,9 +573,14 @@
 					-font->base.scale.yy,
 					0, 0);
 
-    ctFont = CTFontCreateWithGraphicsFont (font_face->cgFont, 1.0, NULL, NULL);
-    glyphPath = CTFontCreatePathForGlyph (ctFont, glyph, &textMatrix);
-    CFRelease (ctFont);
+    if (CTFontCreateWithGraphicsFontPtr && CTFontCreatePathForGlyphPtr) {
+	CTFontRef ctFont = CTFontCreateWithGraphicsFontPtr (font_face->cgFont, 1.0, NULL, NULL);
+	glyphPath = CTFontCreatePathForGlyphPtr (ctFont, glyph, &textMatrix);
+	CFRelease (ctFont);
+    } else {
+	glyphPath = CGFontGetGlyphPathPtr (font_face->cgFont, &textMatrix, 0, glyph);
+    }
+
     if (!glyphPath)
 	return CAIRO_INT_STATUS_UNSUPPORTED;
 
@@ -609,7 +627,7 @@
      * Maybe we should draw a better missing-glyph slug or something,
      * but this is ok for now.
      */
-    if (glyph == INVALID_GLYPH) {
+    if (unlikely (glyph == CGGLYPH_INVALID)) {
 	surface = (cairo_image_surface_t*) cairo_image_surface_create (CAIRO_FORMAT_A8, 2, 2);
 	status = cairo_surface_status ((cairo_surface_t *) surface);
 	if (status)
@@ -748,12 +766,13 @@
 {
     cairo_quartz_scaled_font_t *font = (cairo_quartz_scaled_font_t*) abstract_font;
     cairo_quartz_font_face_t *ffont = _cairo_quartz_scaled_to_face(font);
-    UniChar u = (UniChar) ucs4;
-    CGGlyph glyph;
+    CGGlyph glyph[2];
+    UniChar utf16[2];
 
-    CGFontGetGlyphsForUnicharsPtr (ffont->cgFont, &u, &glyph, 1);
+    int len = _cairo_ucs4_to_utf16 (ucs4, utf16);
+    CGFontGetGlyphsForUnicharsPtr (ffont->cgFont, utf16, glyph, len);
 
-    return glyph;
+    return glyph[0];
 }
 
 static cairo_int_status_t

Modified: trunk/Build/source/libs/cairo/cairo-src/src/cairo-quartz-image-surface.c
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/src/cairo-quartz-image-surface.c	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/src/cairo-quartz-image-surface.c	2018-10-20 03:19:36 UTC (rev 48952)
@@ -332,7 +332,7 @@
     if (format != CAIRO_FORMAT_ARGB32 && format != CAIRO_FORMAT_RGB24)
 	return SURFACE_ERROR_INVALID_FORMAT;
 
-    qisurf = malloc(sizeof(cairo_quartz_image_surface_t));
+    qisurf = _cairo_malloc (sizeof(cairo_quartz_image_surface_t));
     if (qisurf == NULL)
 	return SURFACE_ERROR_NO_MEMORY;
 
@@ -361,7 +361,8 @@
     _cairo_surface_init (&qisurf->base,
 			 &cairo_quartz_image_surface_backend,
 			 NULL, /* device */
-			 _cairo_content_from_format (format));
+			 _cairo_content_from_format (format),
+			 FALSE); /* is_vector */
 
     qisurf->width = width;
     qisurf->height = height;

Modified: trunk/Build/source/libs/cairo/cairo-src/src/cairo-quartz-image.h
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/src/cairo-quartz-image.h	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/src/cairo-quartz-image.h	2018-10-20 03:19:36 UTC (rev 48952)
@@ -1,6 +1,6 @@
 /* cairo - a vector graphics library with display and print output
  *
- * Copyright \xA9 2008 Mozilla Corporation
+ * Copyright © 2008 Mozilla Corporation
  *
  * This library is free software; you can redistribute it and/or
  * modify it either under the terms of the GNU Lesser General Public

Modified: trunk/Build/source/libs/cairo/cairo-src/src/cairo-quartz-private.h
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/src/cairo-quartz-private.h	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/src/cairo-quartz-private.h	2018-10-20 03:19:36 UTC (rev 48952)
@@ -44,12 +44,13 @@
 #include "cairo-quartz.h"
 #include "cairo-surface-clipper-private.h"
 
-#ifdef CGFLOAT_DEFINED
-typedef CGFloat cairo_quartz_float_t;
-#else
-typedef float cairo_quartz_float_t;
+#ifndef CGFLOAT_DEFINED
+/* On 10.4, Quartz APIs used float instead of CGFloat */
+typedef float CGFloat;
 #endif
 
+typedef CGFloat cairo_quartz_float_t;
+
 typedef enum {
     DO_DIRECT,
     DO_SHADING,
@@ -57,6 +58,9 @@
     DO_TILED_IMAGE
 } cairo_quartz_action_t;
 
+/* define CTFontRef for pre-10.5 SDKs */
+typedef const struct __CTFont *CTFontRef;
+
 typedef struct cairo_quartz_surface {
     cairo_surface_t base;
 

Modified: trunk/Build/source/libs/cairo/cairo-src/src/cairo-quartz-surface.c
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/src/cairo-quartz-surface.c	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/src/cairo-quartz-surface.c	2018-10-20 03:19:36 UTC (rev 48952)
@@ -508,9 +508,13 @@
 
     /* Quartz doesn't support SATURATE at all. COLOR_DODGE and
      * COLOR_BURN in Quartz follow the ISO32000 definition, but cairo
-     * uses the definition from the Adobe Supplement.
+     * uses the definition from the Adobe Supplement.  Also fallback
+     * on SOFT_LIGHT and HSL_HUE, because their results are
+     * significantly different from those provided by pixman.
      */
     if (op == CAIRO_OPERATOR_SATURATE ||
+	op == CAIRO_OPERATOR_SOFT_LIGHT ||
+	op == CAIRO_OPERATOR_HSL_HUE ||
 	op == CAIRO_OPERATOR_COLOR_DODGE ||
 	op == CAIRO_OPERATOR_COLOR_BURN)
     {
@@ -605,6 +609,13 @@
 static inline CGInterpolationQuality
 _cairo_quartz_filter_to_quartz (cairo_filter_t filter)
 {
+    /* The CGInterpolationQuality enumeration values seem to have the
+     * following meaning:
+     *  - kCGInterpolationNone: nearest neighbor
+     *  - kCGInterpolationLow: bilinear
+     *  - kCGInterpolationHigh: bicubic? Lanczos?
+     */
+
     switch (filter) {
     case CAIRO_FILTER_NEAREST:
     case CAIRO_FILTER_FAST:
@@ -611,8 +622,12 @@
 	return kCGInterpolationNone;
 
     case CAIRO_FILTER_BEST:
+	return kCGInterpolationHigh;
+
     case CAIRO_FILTER_GOOD:
     case CAIRO_FILTER_BILINEAR:
+	return kCGInterpolationLow;
+
     case CAIRO_FILTER_GAUSSIAN:
 	return kCGInterpolationDefault;
 
@@ -811,7 +826,7 @@
 	}
     }
 
-    source_img = malloc (sizeof (quartz_source_image_t));
+    source_img = _cairo_malloc (sizeof (quartz_source_image_t));
     if (unlikely (source_img == NULL))
 	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
@@ -969,7 +984,7 @@
     if (unlikely (status))
 	return status;
 
-    info = malloc (sizeof (SurfacePatternDrawInfo));
+    info = _cairo_malloc (sizeof (SurfacePatternDrawInfo));
     if (unlikely (!info))
 	return CAIRO_STATUS_NO_MEMORY;
 
@@ -2238,7 +2253,7 @@
     quartz_ensure_symbols ();
 
     /* Init the base surface */
-    surface = malloc (sizeof (cairo_quartz_surface_t));
+    surface = _cairo_malloc (sizeof (cairo_quartz_surface_t));
     if (unlikely (surface == NULL))
 	return (cairo_quartz_surface_t*) _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
 
@@ -2247,7 +2262,8 @@
     _cairo_surface_init (&surface->base,
 			 &cairo_quartz_surface_backend,
 			 NULL, /* device */
-			 content);
+			 content,
+			 FALSE); /* is_vector */
 
     _cairo_surface_clipper_init (&surface->clipper,
 				 _cairo_quartz_surface_clipper_intersect_clip_path);

Modified: trunk/Build/source/libs/cairo/cairo-src/src/cairo-quartz.h
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/src/cairo-quartz.h	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/src/cairo-quartz.h	2018-10-20 03:19:36 UTC (rev 48952)
@@ -1,6 +1,6 @@
 /* cairo - a vector graphics library with display and print output
  *
- * Copyright \xA9 2006, 2007 Mozilla Corporation
+ * Copyright © 2006, 2007 Mozilla Corporation
  *
  * This library is free software; you can redistribute it and/or
  * modify it either under the terms of the GNU Lesser General Public

Modified: trunk/Build/source/libs/cairo/cairo-src/src/cairo-recording-surface-private.h
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/src/cairo-recording-surface-private.h	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/src/cairo-recording-surface-private.h	2018-10-20 03:19:36 UTC (rev 48952)
@@ -49,6 +49,9 @@
     CAIRO_COMMAND_STROKE,
     CAIRO_COMMAND_FILL,
     CAIRO_COMMAND_SHOW_TEXT_GLYPHS,
+
+    /* cairo_tag_begin()/cairo_tag_end() */
+    CAIRO_COMMAND_TAG,
 } cairo_command_type_t;
 
 typedef enum {
@@ -112,6 +115,17 @@
     cairo_scaled_font_t		*scaled_font;
 } cairo_command_show_text_glyphs_t;
 
+typedef struct _cairo_command_tag {
+    cairo_command_header_t       header;
+    cairo_bool_t                 begin;
+    char                        *tag_name;
+    char                        *attributes;
+    cairo_pattern_union_t	 source;
+    cairo_stroke_style_t	 style;
+    cairo_matrix_t		 ctm;
+    cairo_matrix_t		 ctm_inverse;
+} cairo_command_tag_t;
+
 typedef union _cairo_command {
     cairo_command_header_t      header;
 
@@ -120,6 +134,7 @@
     cairo_command_stroke_t			stroke;
     cairo_command_fill_t			fill;
     cairo_command_show_text_glyphs_t		show_text_glyphs;
+    cairo_command_tag_t                         tag;
 } cairo_command_t;
 
 typedef struct _cairo_recording_surface {
@@ -169,7 +184,9 @@
 
 cairo_private cairo_status_t
 _cairo_recording_surface_replay_and_create_regions (cairo_surface_t *surface,
-						    cairo_surface_t *target);
+						    const cairo_matrix_t *surface_transform,
+						    cairo_surface_t *target,
+						    cairo_bool_t surface_is_unbounded);
 cairo_private cairo_status_t
 _cairo_recording_surface_replay_region (cairo_surface_t			*surface,
 					const cairo_rectangle_int_t *surface_extents,

Modified: trunk/Build/source/libs/cairo/cairo-src/src/cairo-recording-surface.c
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/src/cairo-recording-surface.c	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/src/cairo-recording-surface.c	2018-10-20 03:19:36 UTC (rev 48952)
@@ -158,7 +158,7 @@
 static struct bbtree *
 bbtree_new (const cairo_box_t *box, cairo_command_header_t *chain)
 {
-    struct bbtree *bbt = malloc (sizeof (*bbt));
+    struct bbtree *bbt = _cairo_malloc (sizeof (*bbt));
     if (bbt == NULL)
 	return NULL;
     bbt->extents = *box;
@@ -386,7 +386,7 @@
 {
     cairo_recording_surface_t *surface;
 
-    surface = malloc (sizeof (cairo_recording_surface_t));
+    surface = _cairo_malloc (sizeof (cairo_recording_surface_t));
     if (unlikely (surface == NULL))
 	return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
 
@@ -393,7 +393,8 @@
     _cairo_surface_init (&surface->base,
 			 &cairo_recording_surface_backend,
 			 NULL, /* device */
-			 content);
+			 content,
+			 TRUE); /* is_vector */
 
 
     surface->unbounded = TRUE;
@@ -482,7 +483,16 @@
 	    cairo_scaled_font_destroy (command->show_text_glyphs.scaled_font);
 	    break;
 
-	default:
+	case CAIRO_COMMAND_TAG:
+	    free (command->tag.tag_name);
+	    if (command->tag.begin) {
+		free (command->tag.attributes);
+		_cairo_pattern_fini (&command->tag.source.base);
+		_cairo_stroke_style_fini (&command->tag.style);
+	    }
+	    break;
+
+	    default:
 	    ASSERT_NOT_REACHED;
 	}
 
@@ -552,11 +562,11 @@
 {
     struct proxy *proxy;
 
-    proxy = malloc (sizeof (*proxy));
+    proxy = _cairo_malloc (sizeof (*proxy));
     if (unlikely (proxy == NULL))
 	return _cairo_surface_create_in_error (CAIRO_STATUS_NO_MEMORY);
 
-    _cairo_surface_init (&proxy->base, &proxy_backend, NULL, image->content);
+    _cairo_surface_init (&proxy->base, &proxy_backend, NULL, image->content, FALSE);
 
     proxy->image = image;
     _cairo_surface_attach_snapshot (source, &proxy->base, NULL);
@@ -683,21 +693,6 @@
     _cairo_array_init (&surface->commands, sizeof (cairo_command_t *));
 }
 
-static cairo_bool_t
-is_identity_recording_pattern (const cairo_pattern_t *pattern)
-{
-    cairo_surface_t *surface;
-
-    if (pattern->type != CAIRO_PATTERN_TYPE_SURFACE)
-	return FALSE;
-
-    if (!_cairo_matrix_is_identity(&pattern->matrix))
-	return FALSE;
-
-    surface = ((cairo_surface_pattern_t *)pattern)->surface;
-    return surface->backend->type == CAIRO_SURFACE_TYPE_RECORDING;
-}
-
 static cairo_int_status_t
 _cairo_recording_surface_paint (void			  *abstract_surface,
 				cairo_operator_t	   op,
@@ -724,10 +719,6 @@
 	  (surface->base.is_clear || _cairo_pattern_is_opaque_solid (source)))))
     {
 	_cairo_recording_surface_reset (surface);
-	if (is_identity_recording_pattern (source)) {
-	    cairo_surface_t *src = ((cairo_surface_pattern_t *)source)->surface;
-	    return _cairo_recording_surface_replay (src, &surface->base);
-	}
     }
 
     status = _cairo_composite_rectangles_init_for_paint (&composite,
@@ -737,7 +728,7 @@
     if (unlikely (status))
 	return status;
 
-    command = malloc (sizeof (cairo_command_paint_t));
+    command = _cairo_malloc (sizeof (cairo_command_paint_t));
     if (unlikely (command == NULL)) {
 	status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
 	goto CLEANUP_COMPOSITE;
@@ -793,7 +784,7 @@
     if (unlikely (status))
 	return status;
 
-    command = malloc (sizeof (cairo_command_mask_t));
+    command = _cairo_malloc (sizeof (cairo_command_mask_t));
     if (unlikely (command == NULL)) {
 	status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
 	goto CLEANUP_COMPOSITE;
@@ -861,7 +852,7 @@
     if (unlikely (status))
 	return status;
 
-    command = malloc (sizeof (cairo_command_stroke_t));
+    command = _cairo_malloc (sizeof (cairo_command_stroke_t));
     if (unlikely (command == NULL)) {
 	status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
 	goto CLEANUP_COMPOSITE;
@@ -937,7 +928,7 @@
     if (unlikely (status))
 	return status;
 
-    command = malloc (sizeof (cairo_command_fill_t));
+    command = _cairo_malloc (sizeof (cairo_command_fill_t));
     if (unlikely (command == NULL)) {
 	status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
 	goto CLEANUP_COMPOSITE;
@@ -1019,7 +1010,7 @@
     if (unlikely (status))
 	return status;
 
-    command = malloc (sizeof (cairo_command_show_text_glyphs_t));
+    command = _cairo_malloc (sizeof (cairo_command_show_text_glyphs_t));
     if (unlikely (command == NULL)) {
 	status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
 	goto CLEANUP_COMPOSITE;
@@ -1043,7 +1034,7 @@
     command->num_clusters = num_clusters;
 
     if (utf8_len) {
-	command->utf8 = malloc (utf8_len);
+	command->utf8 = _cairo_malloc (utf8_len);
 	if (unlikely (command->utf8 == NULL)) {
 	    status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
 	    goto CLEANUP_ARRAYS;
@@ -1094,6 +1085,90 @@
     return status;
 }
 
+static cairo_int_status_t
+_cairo_recording_surface_tag (void			 *abstract_surface,
+			      cairo_bool_t                begin,
+			      const char                 *tag_name,
+			      const char                 *attributes,
+			      const cairo_pattern_t	 *source,
+			      const cairo_stroke_style_t *style,
+			      const cairo_matrix_t	 *ctm,
+			      const cairo_matrix_t	 *ctm_inverse,
+			      const cairo_clip_t	 *clip)
+{
+    cairo_status_t status;
+    cairo_recording_surface_t *surface = abstract_surface;
+    cairo_command_tag_t *command;
+    cairo_composite_rectangles_t composite;
+
+    TRACE ((stderr, "%s: surface=%d\n", __FUNCTION__, surface->base.unique_id));
+
+    status = _cairo_composite_rectangles_init_for_paint (&composite,
+							 &surface->base,
+							 CAIRO_OPERATOR_SOURCE,
+							 source ? source : &_cairo_pattern_black.base,
+							 clip);
+    if (unlikely (status))
+	return status;
+
+    command = calloc (1, sizeof (cairo_command_tag_t));
+    if (unlikely (command == NULL)) {
+	status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
+	goto CLEANUP_COMPOSITE;
+    }
+
+    status = _command_init (surface,
+			    &command->header, CAIRO_COMMAND_TAG, CAIRO_OPERATOR_SOURCE,
+			    &composite);
+    if (unlikely (status))
+	goto CLEANUP_COMMAND;
+
+    command->begin = begin;
+    command->tag_name = strdup (tag_name);
+    if (begin) {
+	if (attributes)
+	    command->attributes = strdup (attributes);
+
+	status = _cairo_pattern_init_snapshot (&command->source.base, source);
+	if (unlikely (status))
+	    goto CLEANUP_STRINGS;
+
+	status = _cairo_stroke_style_init_copy (&command->style, style);
+	if (unlikely (status))
+	    goto CLEANUP_SOURCE;
+
+	command->ctm = *ctm;
+	command->ctm_inverse = *ctm_inverse;
+    }
+
+    status = _cairo_recording_surface_commit (surface, &command->header);
+    if (unlikely (status)) {
+	if (begin)
+	    goto CLEANUP_STRINGS;
+	else
+	    goto CLEANUP_STYLE;
+    }
+
+    _cairo_recording_surface_destroy_bbtree (surface);
+
+    _cairo_composite_rectangles_fini (&composite);
+    return CAIRO_STATUS_SUCCESS;
+
+  CLEANUP_STYLE:
+    _cairo_stroke_style_fini (&command->style);
+  CLEANUP_SOURCE:
+    _cairo_pattern_fini (&command->source.base);
+  CLEANUP_STRINGS:
+    free (command->tag_name);
+    free (command->attributes);
+  CLEANUP_COMMAND:
+    _cairo_clip_destroy (command->header.clip);
+    free (command);
+  CLEANUP_COMPOSITE:
+    _cairo_composite_rectangles_fini (&composite);
+    return status;
+}
+
 static void
 _command_init_copy (cairo_recording_surface_t *surface,
 		    cairo_command_header_t *dst,
@@ -1117,7 +1192,7 @@
     cairo_command_paint_t *command;
     cairo_status_t status;
 
-    command = malloc (sizeof (*command));
+    command = _cairo_malloc (sizeof (*command));
     if (unlikely (command == NULL)) {
 	status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
 	goto err;
@@ -1151,7 +1226,7 @@
     cairo_command_mask_t *command;
     cairo_status_t status;
 
-    command = malloc (sizeof (*command));
+    command = _cairo_malloc (sizeof (*command));
     if (unlikely (command == NULL)) {
 	status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
 	goto err;
@@ -1192,7 +1267,7 @@
     cairo_command_stroke_t *command;
     cairo_status_t status;
 
-    command = malloc (sizeof (*command));
+    command = _cairo_malloc (sizeof (*command));
     if (unlikely (command == NULL)) {
 	status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
 	goto err;
@@ -1244,7 +1319,7 @@
     cairo_command_fill_t *command;
     cairo_status_t status;
 
-    command = malloc (sizeof (*command));
+    command = _cairo_malloc (sizeof (*command));
     if (unlikely (command == NULL)) {
 	status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
 	goto err;
@@ -1288,7 +1363,7 @@
     cairo_command_show_text_glyphs_t *command;
     cairo_status_t status;
 
-    command = malloc (sizeof (*command));
+    command = _cairo_malloc (sizeof (*command));
     if (unlikely (command == NULL)) {
 	status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
 	goto err;
@@ -1309,7 +1384,7 @@
     command->num_clusters = src->show_text_glyphs.num_clusters;
 
     if (command->utf8_len) {
-	command->utf8 = malloc (command->utf8_len);
+	command->utf8 = _cairo_malloc (command->utf8_len);
 	if (unlikely (command->utf8 == NULL)) {
 	    status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
 	    goto err_arrays;
@@ -1360,6 +1435,63 @@
 }
 
 static cairo_status_t
+_cairo_recording_surface_copy__tag (cairo_recording_surface_t *surface,
+				    const cairo_command_t *src)
+{
+    cairo_command_tag_t *command;
+    cairo_status_t status;
+
+    command = calloc (1, sizeof (*command));
+    if (unlikely (command == NULL)) {
+	status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
+	goto err;
+    }
+
+    _command_init_copy (surface, &command->header, &src->header);
+
+    command->begin = src->tag.begin;
+    command->tag_name = strdup (src->tag.tag_name);
+    if (src->tag.begin) {
+	if (src->tag.attributes)
+	    command->attributes = strdup (src->tag.attributes);
+
+	status = _cairo_pattern_init_copy (&command->source.base,
+					   &src->stroke.source.base);
+	if (unlikely (status))
+	    goto err_command;
+
+	status = _cairo_stroke_style_init_copy (&command->style,
+						&src->stroke.style);
+	if (unlikely (status))
+	    goto err_source;
+
+	command->ctm = src->stroke.ctm;
+	command->ctm_inverse = src->stroke.ctm_inverse;
+    }
+
+    status = _cairo_recording_surface_commit (surface, &command->header);
+    if (unlikely (status)) {
+	if (src->tag.begin)
+	    goto err_command;
+	else
+	    goto err_style;
+    }
+
+    return CAIRO_STATUS_SUCCESS;
+
+err_style:
+    _cairo_stroke_style_fini (&command->style);
+err_source:
+    _cairo_pattern_fini (&command->source.base);
+err_command:
+    free(command->tag_name);
+    free(command->attributes);
+    free(command);
+err:
+    return status;
+}
+
+static cairo_status_t
 _cairo_recording_surface_copy (cairo_recording_surface_t *dst,
 			       cairo_recording_surface_t *src)
 {
@@ -1393,6 +1525,10 @@
 	    status = _cairo_recording_surface_copy__glyphs (dst, command);
 	    break;
 
+	case CAIRO_COMMAND_TAG:
+	    status = _cairo_recording_surface_copy__tag (dst, command);
+	    break;
+
 	default:
 	    ASSERT_NOT_REACHED;
 	}
@@ -1424,7 +1560,7 @@
     cairo_recording_surface_t *surface;
     cairo_status_t status;
 
-    surface = malloc (sizeof (cairo_recording_surface_t));
+    surface = _cairo_malloc (sizeof (cairo_recording_surface_t));
     if (unlikely (surface == NULL))
 	return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
 
@@ -1431,7 +1567,8 @@
     _cairo_surface_init (&surface->base,
 			 &cairo_recording_surface_backend,
 			 NULL, /* device */
-			 other->base.content);
+			 other->base.content,
+			 other->base.is_vector);
 
     surface->extents_pixels = other->extents_pixels;
     surface->extents = other->extents;
@@ -1507,6 +1644,8 @@
     NULL,
     _cairo_recording_surface_has_show_text_glyphs,
     _cairo_recording_surface_show_text_glyphs,
+    NULL, /* get_supported_mime_types */
+    _cairo_recording_surface_tag,
 };
 
 cairo_int_status_t
@@ -1571,6 +1710,9 @@
 	    break;
 	}
 
+	case CAIRO_COMMAND_TAG:
+	    break;
+
 	default:
 	    ASSERT_NOT_REACHED;
 	}
@@ -1674,6 +1816,7 @@
 					  const cairo_matrix_t *surface_transform,
 					  cairo_surface_t	     *target,
 					  const cairo_clip_t *target_clip,
+					  cairo_bool_t surface_is_unbounded,
 					  cairo_recording_replay_type_t type,
 					  cairo_recording_region_type_t region)
 {
@@ -1680,8 +1823,7 @@
     cairo_surface_wrapper_t wrapper;
     cairo_command_t **elements;
     cairo_bool_t replay_all =
-	type == CAIRO_RECORDING_REPLAY &&
-	region == CAIRO_RECORDING_REGION_ALL;
+	type == CAIRO_RECORDING_CREATE_REGIONS || region == CAIRO_RECORDING_REGION_ALL;
     cairo_int_status_t status = CAIRO_STATUS_SUCCESS;
     cairo_rectangle_int_t extents;
     cairo_bool_t use_indices = FALSE;
@@ -1706,7 +1848,7 @@
     if (surface_extents)
 	_cairo_surface_wrapper_intersect_extents (&wrapper, surface_extents);
     r = &_cairo_unbounded_rectangle;
-    if (! surface->unbounded) {
+    if (! surface->unbounded && !surface_is_unbounded) {
 	_cairo_surface_wrapper_intersect_extents (&wrapper, &surface->extents);
 	r = &surface->extents;
     }
@@ -1714,7 +1856,7 @@
     _cairo_surface_wrapper_set_clip (&wrapper, target_clip);
 
     /* Compute the extents of the target clip in recorded device space */
-    if (! _cairo_surface_wrapper_get_target_extents (&wrapper, &extents))
+    if (! _cairo_surface_wrapper_get_target_extents (&wrapper, surface_is_unbounded, &extents))
 	goto done;
 
     surface->has_bilevel_alpha = TRUE;
@@ -1868,11 +2010,23 @@
 	    }
 	    break;
 
+	case CAIRO_COMMAND_TAG:
+	    status = _cairo_surface_wrapper_tag (&wrapper,
+						 command->tag.begin,
+						 command->tag.tag_name,
+						 command->tag.attributes,
+						 &command->tag.source.base,
+						 &command->tag.style,
+						 &command->tag.ctm,
+						 &command->tag.ctm_inverse,
+						 command->header.clip);
+	    break;
+
 	default:
 	    ASSERT_NOT_REACHED;
 	}
 
-	if (type == CAIRO_RECORDING_CREATE_REGIONS) {
+	if (type == CAIRO_RECORDING_CREATE_REGIONS && command->header.region != CAIRO_RECORDING_REGION_NATIVE) {
 	    if (status == CAIRO_INT_STATUS_SUCCESS) {
 		command->header.region = CAIRO_RECORDING_REGION_NATIVE;
 	    } else if (status == CAIRO_INT_STATUS_IMAGE_FALLBACK) {
@@ -1975,6 +2129,18 @@
 							  command->header.clip);
 	break;
 
+    case CAIRO_COMMAND_TAG:
+	status = _cairo_surface_wrapper_tag (&wrapper,
+					     command->tag.begin,
+					     command->tag.tag_name,
+					     command->tag.attributes,
+					     &command->tag.source.base,
+					     &command->tag.style,
+					     &command->tag.ctm,
+					     &command->tag.ctm_inverse,
+					     command->header.clip);
+	break;
+
     default:
 	ASSERT_NOT_REACHED;
     }
@@ -1999,7 +2165,7 @@
 				 cairo_surface_t *target)
 {
     return _cairo_recording_surface_replay_internal ((cairo_recording_surface_t *) surface, NULL, NULL,
-						     target, NULL,
+						     target, NULL, FALSE,
 						     CAIRO_RECORDING_REPLAY,
 						     CAIRO_RECORDING_REGION_ALL);
 }
@@ -2011,7 +2177,7 @@
 					   const cairo_clip_t *target_clip)
 {
     return _cairo_recording_surface_replay_internal ((cairo_recording_surface_t *) surface, NULL, surface_transform,
-						     target, target_clip,
+						     target, target_clip, FALSE,
 						     CAIRO_RECORDING_REPLAY,
 						     CAIRO_RECORDING_REGION_ALL);
 }
@@ -2024,10 +2190,13 @@
  */
 cairo_status_t
 _cairo_recording_surface_replay_and_create_regions (cairo_surface_t *surface,
-						    cairo_surface_t *target)
+						    const cairo_matrix_t *surface_transform,
+						    cairo_surface_t *target,
+						    cairo_bool_t surface_is_unbounded)
 {
-    return _cairo_recording_surface_replay_internal ((cairo_recording_surface_t *) surface, NULL, NULL,
+    return _cairo_recording_surface_replay_internal ((cairo_recording_surface_t *) surface, NULL, surface_transform,
 						     target, NULL,
+						     surface_is_unbounded,
 						     CAIRO_RECORDING_CREATE_REGIONS,
 						     CAIRO_RECORDING_REGION_ALL);
 }
@@ -2040,7 +2209,7 @@
 {
     return _cairo_recording_surface_replay_internal ((cairo_recording_surface_t *) surface,
 						     surface_extents, NULL,
-						     target, NULL,
+						     target, NULL, FALSE,
 						     CAIRO_RECORDING_REPLAY,
 						     region);
 }

Modified: trunk/Build/source/libs/cairo/cairo-src/src/cairo-region.c
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/src/cairo-region.c	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/src/cairo-region.c	2018-10-20 03:19:36 UTC (rev 48952)
@@ -107,6 +107,10 @@
     case CAIRO_STATUS_INVALID_MESH_CONSTRUCTION:
     case CAIRO_STATUS_DEVICE_FINISHED:
     case CAIRO_STATUS_JBIG2_GLOBAL_MISSING:
+    case CAIRO_STATUS_PNG_ERROR:
+    case CAIRO_STATUS_FREETYPE_ERROR:
+    case CAIRO_STATUS_WIN32_GDI_ERROR:
+    case CAIRO_STATUS_TAG_ERROR:
     default:
 	_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
 	return (cairo_region_t *) &_cairo_region_nil;
@@ -175,7 +179,7 @@
 {
     assert (! CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&region->ref_count));
     pixman_region32_fini (&region->rgn);
-    VG (VALGRIND_MAKE_MEM_NOACCESS (region, sizeof (cairo_region_t)));
+    VG (VALGRIND_MAKE_MEM_UNDEFINED (region, sizeof (cairo_region_t)));
 }
 
 /**

Modified: trunk/Build/source/libs/cairo/cairo-src/src/cairo-scaled-font-private.h
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/src/cairo-scaled-font-private.h	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/src/cairo-scaled-font-private.h	2018-10-20 03:19:36 UTC (rev 48952)
@@ -141,6 +141,7 @@
     cairo_image_surface_t   *surface;		/* device-space image */
     cairo_path_fixed_t	    *path;		/* device-space outline */
     cairo_surface_t         *recording_surface;	/* device-space recording-surface */
+    cairo_image_surface_t   *color_surface;	/* device-space color image */
 
     const void		   *dev_private_key;
     void		   *dev_private;
@@ -177,6 +178,8 @@
 				   void (*destroy) (cairo_scaled_glyph_private_t *,
 						    cairo_scaled_glyph_t *,
 						    cairo_scaled_font_t *));
+cairo_private cairo_bool_t
+_cairo_scaled_font_has_color_glyphs (cairo_scaled_font_t *scaled_font);
 
 CAIRO_END_DECLS
 

Modified: trunk/Build/source/libs/cairo/cairo-src/src/cairo-scaled-font-subsets.c
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/src/cairo-scaled-font-subsets.c	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/src/cairo-scaled-font-subsets.c	2018-10-20 03:19:36 UTC (rev 48952)
@@ -167,7 +167,7 @@
 {
     cairo_sub_font_glyph_t *sub_font_glyph;
 
-    sub_font_glyph = malloc (sizeof (cairo_sub_font_glyph_t));
+    sub_font_glyph = _cairo_malloc (sizeof (cairo_sub_font_glyph_t));
     if (unlikely (sub_font_glyph == NULL)) {
 	_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
 	return NULL;
@@ -277,7 +277,7 @@
     cairo_sub_font_t *sub_font;
     int i;
 
-    sub_font = malloc (sizeof (cairo_sub_font_t));
+    sub_font = _cairo_malloc (sizeof (cairo_sub_font_t));
     if (unlikely (sub_font == NULL))
 	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
@@ -404,7 +404,7 @@
     if (unicode != (uint32_t) -1) {
 	len = _cairo_ucs4_to_utf8 (unicode, buf);
 	if (len > 0) {
-	    *utf8_out = malloc (len + 1);
+	    *utf8_out = _cairo_malloc (len + 1);
 	    if (unlikely (*utf8_out == NULL))
 		return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
@@ -441,7 +441,7 @@
 	    }
 	} else {
 	    /* No existing mapping. Use the requested mapping */
-	    sub_font_glyph->utf8 = malloc (utf8_len + 1);
+	    sub_font_glyph->utf8 = _cairo_malloc (utf8_len + 1);
 	    if (unlikely (sub_font_glyph->utf8 == NULL))
 		return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
@@ -611,7 +611,7 @@
 		if (ucs4_len == 1) {
 		    font_unicode = ucs4[0];
 		    free (font_utf8);
-		    font_utf8 = malloc (text_utf8_len + 1);
+		    font_utf8 = _cairo_malloc (text_utf8_len + 1);
 		    if (font_utf8 == NULL) {
 			free (ucs4);
 			return _cairo_error (CAIRO_STATUS_NO_MEMORY);
@@ -762,7 +762,7 @@
 {
     cairo_scaled_font_subsets_t *subsets;
 
-    subsets = malloc (sizeof (cairo_scaled_font_subsets_t));
+    subsets = _cairo_malloc (sizeof (cairo_scaled_font_subsets_t));
     if (unlikely (subsets == NULL)) {
 	_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
 	return NULL;
@@ -1217,7 +1217,7 @@
 static cairo_status_t
 create_string_entry (char *s, cairo_string_entry_t **entry)
 {
-    *entry = malloc (sizeof (cairo_string_entry_t));
+    *entry = _cairo_malloc (sizeof (cairo_string_entry_t));
     if (unlikely (*entry == NULL))
 	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 

Modified: trunk/Build/source/libs/cairo/cairo-src/src/cairo-scaled-font.c
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/src/cairo-scaled-font.c	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/src/cairo-scaled-font.c	2018-10-20 03:19:36 UTC (rev 48952)
@@ -46,12 +46,6 @@
 #include "cairo-scaled-font-private.h"
 #include "cairo-surface-backend-private.h"
 
-#if _XOPEN_SOURCE >= 600 || defined (_ISOC99_SOURCE)
-#define ISFINITE(x) isfinite (x)
-#else
-#define ISFINITE(x) ((x) * (x) >= 0.) /* check for NaNs */
-#endif
-
 /**
  * SECTION:cairo-scaled-font
  * @Title: cairo_scaled_font_t
@@ -85,7 +79,7 @@
 #define CAIRO_SCALED_GLYPH_PAGE_SIZE 32
 struct _cairo_scaled_glyph_page {
     cairo_cache_entry_t cache_entry;
-
+    cairo_scaled_font_t *scaled_font;
     cairo_list_t link;
 
     unsigned int num_glyphs;
@@ -224,6 +218,9 @@
 	cairo_surface_finish (scaled_glyph->recording_surface);
 	cairo_surface_destroy (scaled_glyph->recording_surface);
     }
+
+    if (scaled_glyph->color_surface != NULL)
+	cairo_surface_destroy (&scaled_glyph->color_surface->base);
 }
 
 #define ZOMBIE 0
@@ -371,7 +368,7 @@
     CAIRO_MUTEX_LOCK (_cairo_scaled_font_map_mutex);
 
     if (cairo_scaled_font_map == NULL) {
-	cairo_scaled_font_map = malloc (sizeof (cairo_scaled_font_map_t));
+	cairo_scaled_font_map = _cairo_malloc (sizeof (cairo_scaled_font_map_t));
 	if (unlikely (cairo_scaled_font_map == NULL))
 	    goto CLEANUP_MUTEX_LOCK;
 
@@ -477,7 +474,7 @@
 
     assert (! cairo_list_is_empty (&page->link));
 
-    scaled_font = (cairo_scaled_font_t *) page->cache_entry.hash;
+    scaled_font = page->scaled_font;
 
     CAIRO_MUTEX_LOCK (scaled_font->mutex);
     _cairo_scaled_glyph_page_destroy (scaled_font, page);
@@ -512,7 +509,7 @@
     if (unlikely (status))
 	return status;
 
-    placeholder_scaled_font = malloc (sizeof (cairo_scaled_font_t));
+    placeholder_scaled_font = _cairo_malloc (sizeof (cairo_scaled_font_t));
     if (unlikely (placeholder_scaled_font == NULL))
 	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
@@ -1229,7 +1226,7 @@
     CAIRO_MUTEX_LOCK (_cairo_scaled_font_error_mutex);
     scaled_font = _cairo_scaled_font_nil_objects[status];
     if (unlikely (scaled_font == NULL)) {
-	scaled_font = malloc (sizeof (cairo_scaled_font_t));
+	scaled_font = _cairo_malloc (sizeof (cairo_scaled_font_t));
 	if (unlikely (scaled_font == NULL)) {
 	    CAIRO_MUTEX_UNLOCK (_cairo_scaled_font_error_mutex);
 	    _cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
@@ -1277,8 +1274,8 @@
  * @scaled_font from being destroyed until a matching call to
  * cairo_scaled_font_destroy() is made.
  *
- * The number of references to a #cairo_scaled_font_t can be get using
- * cairo_scaled_font_get_reference_count().
+ * Use cairo_scaled_font_get_reference_count() to get the number of
+ * references to a #cairo_scaled_font_t.
  *
  * Returns: the referenced #cairo_scaled_font_t
  *
@@ -2055,7 +2052,7 @@
 		    status = _cairo_error (CAIRO_STATUS_NEGATIVE_COUNT);
 		    goto DONE;
 		}
-		if (num_glyphs && *glyphs == NULL) {
+		if (*num_glyphs != 0 && *glyphs == NULL) {
 		    status = _cairo_error (CAIRO_STATUS_NULL_POINTER);
 		    goto DONE;
 		}
@@ -2065,7 +2062,7 @@
 			status = _cairo_error (CAIRO_STATUS_NEGATIVE_COUNT);
 			goto DONE;
 		    }
-		    if (num_clusters && *clusters == NULL) {
+		    if (*num_clusters != 0 && *clusters == NULL) {
 			status = _cairo_error (CAIRO_STATUS_NULL_POINTER);
 			goto DONE;
 		    }
@@ -2830,6 +2827,24 @@
 	scaled_glyph->has_info &= ~CAIRO_SCALED_GLYPH_INFO_RECORDING_SURFACE;
 }
 
+void
+_cairo_scaled_glyph_set_color_surface (cairo_scaled_glyph_t *scaled_glyph,
+	                               cairo_scaled_font_t *scaled_font,
+	                               cairo_image_surface_t *surface)
+{
+    if (scaled_glyph->color_surface != NULL)
+	cairo_surface_destroy (&scaled_glyph->color_surface->base);
+
+    /* sanity check the backend glyph contents */
+    _cairo_debug_check_image_surface_is_defined (&surface->base);
+    scaled_glyph->color_surface = surface;
+
+    if (surface != NULL)
+	scaled_glyph->has_info |= CAIRO_SCALED_GLYPH_INFO_COLOR_SURFACE;
+    else
+	scaled_glyph->has_info &= ~CAIRO_SCALED_GLYPH_INFO_COLOR_SURFACE;
+}
+
 static cairo_bool_t
 _cairo_scaled_glyph_page_can_remove (const void *closure)
 {
@@ -2836,7 +2851,7 @@
     const cairo_scaled_glyph_page_t *page = closure;
     const cairo_scaled_font_t *scaled_font;
 
-    scaled_font = (cairo_scaled_font_t *) page->cache_entry.hash;
+    scaled_font = page->scaled_font;
     return scaled_font->cache_frozen == 0;
 }
 
@@ -2860,11 +2875,12 @@
         }
     }
 
-    page = malloc (sizeof (cairo_scaled_glyph_page_t));
+    page = _cairo_malloc (sizeof (cairo_scaled_glyph_page_t));
     if (unlikely (page == NULL))
 	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
     page->cache_entry.hash = (unsigned long) scaled_font;
+    page->scaled_font = scaled_font;
     page->cache_entry.size = 1; /* XXX occupancy weighting? */
     page->num_glyphs = 0;
 
@@ -3175,3 +3191,12 @@
     _cairo_font_options_init_copy (options, &scaled_font->options);
 }
 slim_hidden_def (cairo_scaled_font_get_font_options);
+
+cairo_bool_t
+_cairo_scaled_font_has_color_glyphs (cairo_scaled_font_t *scaled_font)
+{
+    if (scaled_font->backend != NULL && scaled_font->backend->has_color_glyphs != NULL)
+        return scaled_font->backend->has_color_glyphs (scaled_font);
+    else
+       return FALSE;
+}

Modified: trunk/Build/source/libs/cairo/cairo-src/src/cairo-script-surface.c
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/src/cairo-script-surface.c	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/src/cairo-script-surface.c	2018-10-20 03:19:36 UTC (rev 48952)
@@ -262,8 +262,9 @@
 	prev = &b->next;
 	b = b->next;
     } while (b != NULL);
+    assert (prev != NULL);
 
-    bb = malloc (sizeof (struct _bitmap));
+    bb = _cairo_malloc (sizeof (struct _bitmap));
     if (unlikely (bb == NULL))
 	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
@@ -1104,7 +1105,7 @@
     if (! ctx->attach_snapshots)
 	return;
 
-    surface = malloc (sizeof (*surface));
+    surface = _cairo_malloc (sizeof (*surface));
     if (unlikely (surface == NULL))
 	return;
 
@@ -1111,7 +1112,8 @@
     _cairo_surface_init (&surface->base,
 			 &script_snapshot_backend,
 			 &ctx->base,
-			 source->content);
+			 source->content,
+			 source->is_vector);
 
     _cairo_output_stream_printf (ctx->stream,
 				 "dup /s%d exch def ",
@@ -1201,7 +1203,8 @@
 _write_image_surface (cairo_output_stream_t *output,
 		      const cairo_image_surface_t *image)
 {
-    int stride, row, width;
+    int row, width;
+    ptrdiff_t stride;
     uint8_t row_stack[CAIRO_STACK_BUFFER_SIZE];
     uint8_t *rowdata;
     uint8_t *data;
@@ -1253,7 +1256,7 @@
     }
 #else
     if (stride > ARRAY_LENGTH (row_stack)) {
-	rowdata = malloc (stride);
+	rowdata = _cairo_malloc (stride);
 	if (unlikely (rowdata == NULL))
 	    return _cairo_error (CAIRO_STATUS_NO_MEMORY);
     } else
@@ -2176,7 +2179,7 @@
 		}
 		cairo_list_del (&surface->operand.link);
 	    } else {
-		struct deferred_finish *link = malloc (sizeof (*link));
+		struct deferred_finish *link = _cairo_malloc (sizeof (*link));
 		if (link == NULL) {
 		    status2 = _cairo_error (CAIRO_STATUS_NO_MEMORY);
 		    if (status == CAIRO_STATUS_SUCCESS)
@@ -2855,7 +2858,7 @@
     if (unlikely (status))
 	return status;
 
-    buf = malloc (size);
+    buf = _cairo_malloc (size);
     if (unlikely (buf == NULL))
 	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
@@ -2911,7 +2914,7 @@
     cairo_script_font_t *font_private;
     cairo_int_status_t status;
 
-    font_private = malloc (sizeof (cairo_script_font_t));
+    font_private = _cairo_malloc (sizeof (cairo_script_font_t));
     if (unlikely (font_private == NULL))
 	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
@@ -3641,7 +3644,7 @@
     if (unlikely (ctx == NULL))
 	return (cairo_script_surface_t *) _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NULL_POINTER));
 
-    surface = malloc (sizeof (cairo_script_surface_t));
+    surface = _cairo_malloc (sizeof (cairo_script_surface_t));
     if (unlikely (surface == NULL))
 	return (cairo_script_surface_t *) _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
 
@@ -3648,7 +3651,8 @@
     _cairo_surface_init (&surface->base,
 			 &_cairo_script_surface_backend,
 			 &ctx->base,
-			 content);
+			 content,
+			 TRUE); /* is_vector */
 
     _cairo_surface_wrapper_init (&surface->wrapper, passthrough);
 
@@ -3689,7 +3693,7 @@
 {
     cairo_script_context_t *ctx;
 
-    ctx = malloc (sizeof (cairo_script_context_t));
+    ctx = _cairo_malloc (sizeof (cairo_script_context_t));
     if (unlikely (ctx == NULL))
 	return _cairo_device_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
 

Deleted: trunk/Build/source/libs/cairo/cairo-src/src/cairo-skia.h
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/src/cairo-skia.h	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/src/cairo-skia.h	2018-10-20 03:19:36 UTC (rev 48952)
@@ -1,66 +0,0 @@
-/* cairo - a vector graphics library with display and print output
- *
- * Copyright © 2002 University of Southern California
- *
- * This library is free software; you can redistribute it and/or
- * modify it either under the terms of the GNU Lesser General Public
- * License version 2.1 as published by the Free Software Foundation
- * (the "LGPL") or, at your option, under the terms of the Mozilla
- * Public License Version 1.1 (the "MPL"). If you do not alter this
- * notice, a recipient may use your version of this file under either
- * the MPL or the LGPL.
- *
- * You should have received a copy of the LGPL along with this library
- * in the file COPYING-LGPL-2.1; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
- * You should have received a copy of the MPL along with this library
- * in the file COPYING-MPL-1.1
- *
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
- * OF ANY KIND, either express or implied. See the LGPL or the MPL for
- * the specific language governing rights and limitations.
- *
- * The Original Code is the cairo graphics library.
- *
- * The Initial Developer of the Original Code is University of Southern
- * California.
- *
- * Contributor(s):
- *	Carl D. Worth <cworth at cworth.org>
- */
-
-#ifndef CAIRO_SKIA_H
-#define CAIRO_SKIA_H
-
-#include "cairo.h"
-
-#if CAIRO_HAS_SKIA_SURFACE
-
-CAIRO_BEGIN_DECLS
-
-cairo_public cairo_surface_t *
-cairo_skia_surface_create (cairo_format_t format,
-			   int width,
-			   int height);
-
-cairo_public cairo_surface_t *
-cairo_skia_surface_create_for_data (unsigned char *data,
-				    cairo_format_t format,
-				    int width,
-				    int height,
-				    int stride);
-
-CAIRO_END_DECLS
-
-#else
-
-# error Cairo was not compiled with support for the Skia backend
-
-#endif
-
-#endif

Modified: trunk/Build/source/libs/cairo/cairo-src/src/cairo-spans-private.h
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/src/cairo-spans-private.h	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/src/cairo-spans-private.h	2018-10-20 03:19:36 UTC (rev 48952)
@@ -168,6 +168,10 @@
 				  const cairo_box_t *extents,
 				  cairo_fill_rule_t fill_rule);
 
+cairo_private cairo_status_t
+_cairo_botor_scan_converter_add_polygon (cairo_botor_scan_converter_t *converter,
+					const cairo_polygon_t *polygon);
+
 /* cairo-spans.c: */
 
 cairo_private cairo_scan_converter_t *

Modified: trunk/Build/source/libs/cairo/cairo-src/src/cairo-spans.c
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/src/cairo-spans.c	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/src/cairo-spans.c	2018-10-20 03:19:36 UTC (rev 48952)
@@ -128,6 +128,10 @@
     case CAIRO_STATUS_INVALID_MESH_CONSTRUCTION: RETURN_NIL;
     case CAIRO_STATUS_DEVICE_FINISHED: RETURN_NIL;
     case CAIRO_STATUS_JBIG2_GLOBAL_MISSING:
+    case CAIRO_STATUS_PNG_ERROR:
+    case CAIRO_STATUS_FREETYPE_ERROR:
+    case CAIRO_STATUS_WIN32_GDI_ERROR:
+    case CAIRO_STATUS_TAG_ERROR:
     default:
 	break;
     }
@@ -241,6 +245,10 @@
     case CAIRO_STATUS_INVALID_MESH_CONSTRUCTION: RETURN_NIL;
     case CAIRO_STATUS_DEVICE_FINISHED: RETURN_NIL;
     case CAIRO_STATUS_JBIG2_GLOBAL_MISSING: RETURN_NIL;
+    case CAIRO_STATUS_PNG_ERROR: RETURN_NIL;
+    case CAIRO_STATUS_FREETYPE_ERROR: RETURN_NIL;
+    case CAIRO_STATUS_WIN32_GDI_ERROR: RETURN_NIL;
+    case CAIRO_STATUS_TAG_ERROR: RETURN_NIL;
     default:
 	break;
     }

Modified: trunk/Build/source/libs/cairo/cairo-src/src/cairo-stroke-style.c
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/src/cairo-stroke-style.c	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/src/cairo-stroke-style.c	2018-10-20 03:19:36 UTC (rev 48952)
@@ -91,7 +91,7 @@
 
     style->num_dashes = 0;
 
-    VG (VALGRIND_MAKE_MEM_NOACCESS (style, sizeof (cairo_stroke_style_t)));
+    VG (VALGRIND_MAKE_MEM_UNDEFINED (style, sizeof (cairo_stroke_style_t)));
 }
 
 /*

Modified: trunk/Build/source/libs/cairo/cairo-src/src/cairo-surface-backend-private.h
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/src/cairo-surface-backend-private.h	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/src/cairo-surface-backend-private.h	2018-10-20 03:19:36 UTC (rev 48952)
@@ -200,6 +200,18 @@
 
     const char **
     (*get_supported_mime_types)	(void			    *surface);
+
+    cairo_warn cairo_int_status_t
+    (*tag)			(void			*surface,
+				 cairo_bool_t            begin,
+				 const char             *tag_name,
+				 const char             *attributes,
+				 const cairo_pattern_t	*source,
+				 const cairo_stroke_style_t	*style,
+				 const cairo_matrix_t	*ctm,
+				 const cairo_matrix_t	*ctm_inverse,
+				 const cairo_clip_t	*clip);
+
 };
 
 cairo_private cairo_status_t

Modified: trunk/Build/source/libs/cairo/cairo-src/src/cairo-surface-observer.c
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/src/cairo-surface-observer.c	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/src/cairo-surface-observer.c	2018-10-20 03:19:36 UTC (rev 48952)
@@ -348,7 +348,7 @@
     cairo_device_observer_t *device;
     cairo_status_t status;
 
-    device = malloc (sizeof (cairo_device_observer_t));
+    device = _cairo_malloc (sizeof (cairo_device_observer_t));
     if (unlikely (device == NULL))
 	return _cairo_device_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
 
@@ -379,13 +379,14 @@
     cairo_surface_observer_t *surface;
     cairo_status_t status;
 
-    surface = malloc (sizeof (cairo_surface_observer_t));
+    surface = _cairo_malloc (sizeof (cairo_surface_observer_t));
     if (unlikely (surface == NULL))
 	return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
 
     _cairo_surface_init (&surface->base,
 			 &_cairo_surface_observer_backend, device,
-			 target->content);
+			 target->content,
+			 target->is_vector);
 
     status = log_init (&surface->log,
 		       ((cairo_device_observer_t *)device)->log.record != NULL);
@@ -1417,7 +1418,7 @@
 {
     struct callback_list *cb;
 
-    cb = malloc (sizeof (*cb));
+    cb = _cairo_malloc (sizeof (*cb));
     if (unlikely (cb == NULL))
 	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 

Modified: trunk/Build/source/libs/cairo/cairo-src/src/cairo-surface-private.h
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/src/cairo-surface-private.h	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/src/cairo-surface-private.h	2018-10-20 03:19:36 UTC (rev 48952)
@@ -70,6 +70,7 @@
     unsigned is_clear : 1;
     unsigned has_font_options : 1;
     unsigned owns_device : 1;
+    unsigned is_vector : 1;
 
     cairo_user_data_array_t user_data;
     cairo_user_data_array_t mime_data;

Modified: trunk/Build/source/libs/cairo/cairo-src/src/cairo-surface-snapshot.c
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/src/cairo-surface-snapshot.c	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/src/cairo-surface-snapshot.c	2018-10-20 03:19:36 UTC (rev 48952)
@@ -99,9 +99,11 @@
     struct snapshot_extra *extra;
     cairo_status_t status;
 
-    extra = malloc (sizeof (*extra));
-    if (unlikely (extra == NULL))
+    extra = _cairo_malloc (sizeof (*extra));
+    if (unlikely (extra == NULL)) {
+	*extra_out = NULL;
 	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
+    }
 
     extra->target = _cairo_surface_snapshot_get_target (&surface->base);
     status =  _cairo_surface_acquire_source_image (extra->target, image_out, &extra->extra);
@@ -108,6 +110,7 @@
     if (unlikely (status)) {
 	cairo_surface_destroy (extra->target);
 	free (extra);
+	extra = NULL;
     }
 
     *extra_out = extra;
@@ -258,7 +261,7 @@
     if (snapshot != NULL)
 	return cairo_surface_reference (&snapshot->base);
 
-    snapshot = malloc (sizeof (cairo_surface_snapshot_t));
+    snapshot = _cairo_malloc (sizeof (cairo_surface_snapshot_t));
     if (unlikely (snapshot == NULL))
 	return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_SURFACE_FINISHED));
 
@@ -265,7 +268,8 @@
     _cairo_surface_init (&snapshot->base,
 			 &_cairo_surface_snapshot_backend,
 			 NULL, /* device */
-			 surface->content);
+			 surface->content,
+			 surface->is_vector);
     snapshot->base.type = surface->type;
 
     CAIRO_MUTEX_INIT (snapshot->mutex);

Modified: trunk/Build/source/libs/cairo/cairo-src/src/cairo-surface-subsurface.c
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/src/cairo-surface-subsurface.c	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/src/cairo-surface-subsurface.c	2018-10-20 03:19:36 UTC (rev 48952)
@@ -462,7 +462,7 @@
     if (unlikely (target->finished))
 	return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_SURFACE_FINISHED));
 
-    surface = malloc (sizeof (cairo_surface_subsurface_t));
+    surface = _cairo_malloc (sizeof (cairo_surface_subsurface_t));
     if (unlikely (surface == NULL))
 	return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
 
@@ -478,7 +478,8 @@
     _cairo_surface_init (&surface->base,
 			 &_cairo_surface_subsurface_backend,
 			 NULL, /* device */
-			 target->content);
+			 target->content,
+			 target->is_vector);
 
     /* XXX forced integer alignment */
     surface->extents.x = ceil (x);
@@ -521,7 +522,7 @@
 
     assert (target->backend->type != CAIRO_SURFACE_TYPE_SUBSURFACE);
 
-    surface = malloc (sizeof (cairo_surface_subsurface_t));
+    surface = _cairo_malloc (sizeof (cairo_surface_subsurface_t));
     if (unlikely (surface == NULL))
 	return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
 
@@ -528,7 +529,8 @@
     _cairo_surface_init (&surface->base,
 			 &_cairo_surface_subsurface_backend,
 			 NULL, /* device */
-			 target->content);
+			 target->content,
+			 target->is_vector);
 
     surface->extents = *extents;
     surface->extents.x *= target->device_transform.xx;

Modified: trunk/Build/source/libs/cairo/cairo-src/src/cairo-surface-wrapper-private.h
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/src/cairo-surface-wrapper-private.h	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/src/cairo-surface-wrapper-private.h	2018-10-20 03:19:36 UTC (rev 48952)
@@ -159,6 +159,17 @@
 					 cairo_scaled_font_t	    *scaled_font,
 					 const cairo_clip_t	    *clip);
 
+cairo_private cairo_status_t
+_cairo_surface_wrapper_tag (cairo_surface_wrapper_t     *wrapper,
+			    cairo_bool_t                 begin,
+			    const char                  *tag_name,
+			    const char                  *attributes,
+			    const cairo_pattern_t	*source,
+			    const cairo_stroke_style_t	*stroke_style,
+			    const cairo_matrix_t	*ctm,
+			    const cairo_matrix_t	*ctm_inverse,
+			    const cairo_clip_t		*clip);
+
 cairo_private cairo_surface_t *
 _cairo_surface_wrapper_create_similar (cairo_surface_wrapper_t *wrapper,
 				       cairo_content_t	content,
@@ -186,6 +197,7 @@
 
 cairo_private cairo_bool_t
 _cairo_surface_wrapper_get_target_extents (cairo_surface_wrapper_t *wrapper,
+					   cairo_bool_t surface_is_unbounded,
 					   cairo_rectangle_int_t *extents);
 
 CAIRO_END_DECLS

Modified: trunk/Build/source/libs/cairo/cairo-src/src/cairo-surface-wrapper.c
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/src/cairo-surface-wrapper.c	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/src/cairo-surface-wrapper.c	2018-10-20 03:19:36 UTC (rev 48952)
@@ -81,9 +81,6 @@
 {
     cairo_matrix_init_identity (m);
 
-    if (wrapper->has_extents && (wrapper->extents.x || wrapper->extents.y))
-	cairo_matrix_translate (m, -wrapper->extents.x, -wrapper->extents.y);
-
     if (! _cairo_matrix_is_identity (&wrapper->transform))
 	cairo_matrix_multiply (m, &wrapper->transform, m);
 
@@ -109,9 +106,6 @@
 	assert (status == CAIRO_STATUS_SUCCESS);
 	cairo_matrix_multiply (m, &inv, m);
     }
-
-    if (wrapper->has_extents && (wrapper->extents.x || wrapper->extents.y))
-	cairo_matrix_translate (m, wrapper->extents.x, wrapper->extents.y);
 }
 
 static cairo_clip_t *
@@ -119,14 +113,14 @@
 				 const cairo_clip_t *clip)
 {
     cairo_clip_t *copy;
+    cairo_matrix_t m;
 
     copy = _cairo_clip_copy (clip);
     if (wrapper->has_extents) {
 	copy = _cairo_clip_intersect_rectangle (copy, &wrapper->extents);
     }
-    copy = _cairo_clip_transform (copy, &wrapper->transform);
-    if (! _cairo_matrix_is_identity (&wrapper->target->device_transform))
-	copy = _cairo_clip_transform (copy, &wrapper->target->device_transform);
+    _cairo_surface_wrapper_get_transform (wrapper, &m);
+    copy = _cairo_clip_transform (copy, &m);
     if (wrapper->clip)
 	copy = _cairo_clip_intersect_clip (copy, wrapper->clip);
 
@@ -507,6 +501,53 @@
     return status;
 }
 
+cairo_status_t
+_cairo_surface_wrapper_tag (cairo_surface_wrapper_t     *wrapper,
+			    cairo_bool_t                 begin,
+			    const char                  *tag_name,
+			    const char                  *attributes,
+			    const cairo_pattern_t	*source,
+			    const cairo_stroke_style_t	*stroke_style,
+			    const cairo_matrix_t	*ctm,
+			    const cairo_matrix_t	*ctm_inverse,
+			    const cairo_clip_t		*clip)
+{
+    cairo_status_t status;
+    cairo_clip_t *dev_clip;
+    cairo_matrix_t dev_ctm = *ctm;
+    cairo_matrix_t dev_ctm_inverse = *ctm_inverse;
+    cairo_pattern_union_t source_copy;
+
+    if (unlikely (wrapper->target->status))
+	return wrapper->target->status;
+
+    dev_clip = _cairo_surface_wrapper_get_clip (wrapper, clip);
+    if (wrapper->needs_transform) {
+	cairo_matrix_t m;
+
+	_cairo_surface_wrapper_get_transform (wrapper, &m);
+
+	cairo_matrix_multiply (&dev_ctm, &dev_ctm, &m);
+
+	status = cairo_matrix_invert (&m);
+	assert (status == CAIRO_STATUS_SUCCESS);
+
+	cairo_matrix_multiply (&dev_ctm_inverse, &m, &dev_ctm_inverse);
+
+	_copy_transformed_pattern (&source_copy.base, source, &m);
+	source = &source_copy.base;
+    }
+
+    status = _cairo_surface_tag (wrapper->target,
+				 begin, tag_name, attributes,
+				 source, stroke_style,
+				 &dev_ctm, &dev_ctm_inverse,
+				 dev_clip);
+
+    _cairo_clip_destroy (dev_clip);
+    return status;
+}
+
 cairo_surface_t *
 _cairo_surface_wrapper_create_similar (cairo_surface_wrapper_t *wrapper,
 				       cairo_content_t	content,
@@ -631,12 +672,15 @@
 
 cairo_bool_t
 _cairo_surface_wrapper_get_target_extents (cairo_surface_wrapper_t *wrapper,
+					   cairo_bool_t surface_is_unbounded,
 					   cairo_rectangle_int_t *extents)
 {
     cairo_rectangle_int_t clip;
-    cairo_bool_t has_clip;
+    cairo_bool_t has_clip = FALSE;
 
-    has_clip = _cairo_surface_get_extents (wrapper->target, &clip);
+    if (!surface_is_unbounded)
+	has_clip = _cairo_surface_get_extents (wrapper->target, &clip);
+
     if (wrapper->clip) {
 	if (has_clip) {
 	    if (! _cairo_rectangle_intersect (&clip,

Modified: trunk/Build/source/libs/cairo/cairo-src/src/cairo-surface.c
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/src/cairo-surface.c	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/src/cairo-surface.c	2018-10-20 03:19:36 UTC (rev 48952)
@@ -113,7 +113,8 @@
     FALSE,				/* finished */		\
     TRUE,				/* is_clear */		\
     FALSE,				/* has_font_options */	\
-    FALSE,				/* owns_device */	\
+    FALSE,				/* owns_device */ \
+    FALSE,                              /* is_vector */ \
     { 0, 0, 0, NULL, },			/* user_data */		\
     { 0, 0, 0, NULL, },			/* mime_data */         \
     { 1.0, 0.0, 0.0, 1.0, 0.0, 0.0 },   /* device_transform */	\
@@ -400,7 +401,8 @@
 _cairo_surface_init (cairo_surface_t			*surface,
 		     const cairo_surface_backend_t	*backend,
 		     cairo_device_t			*device,
-		     cairo_content_t			 content)
+		     cairo_content_t			 content,
+		     cairo_bool_t                        is_vector)
 {
     CAIRO_MUTEX_INITIALIZE ();
 
@@ -408,6 +410,7 @@
     surface->device = cairo_device_reference (device);
     surface->content = content;
     surface->type = backend->type;
+    surface->is_vector = is_vector;
 
     CAIRO_REFERENCE_COUNT_INIT (&surface->ref_count, 1);
     surface->status = CAIRO_STATUS_SUCCESS;
@@ -501,13 +504,9 @@
 	return _cairo_surface_create_in_error (CAIRO_STATUS_SURFACE_FINISHED);
     if (unlikely (width < 0 || height < 0))
 	return _cairo_surface_create_in_error (CAIRO_STATUS_INVALID_SIZE);
-
     if (unlikely (! CAIRO_CONTENT_VALID (content)))
 	return _cairo_surface_create_in_error (CAIRO_STATUS_INVALID_CONTENT);
 
-        if (unlikely (other->status))
-	return _cairo_surface_create_in_error (other->status);
-
     /* We inherit the device scale, so create a larger surface */
     width = width * other->device_transform.xx;
     height = height * other->device_transform.yy;
@@ -914,8 +913,8 @@
  * @surface from being destroyed until a matching call to
  * cairo_surface_destroy() is made.
  *
- * The number of references to a #cairo_surface_t can be get using
- * cairo_surface_get_reference_count().
+ * Use cairo_surface_get_reference_count() to get the number of
+ * references to a #cairo_surface_t.
  *
  * Return value: the referenced #cairo_surface_t.
  *
@@ -1026,8 +1025,6 @@
 {
     cairo_status_t status;
 
-    surface->finished = TRUE;
-
     /* call finish even if in error mode */
     if (surface->backend->finish) {
 	status = surface->backend->finish (surface);
@@ -1035,6 +1032,8 @@
 	    _cairo_surface_set_error (surface, status);
     }
 
+    surface->finished = TRUE;
+
     assert (surface->snapshot_of == NULL);
     assert (!_cairo_surface_has_snapshots (surface));
 }
@@ -1225,7 +1224,81 @@
     free (mime_data);
 }
 
+
+static const char *_cairo_surface_image_mime_types[] = {
+    CAIRO_MIME_TYPE_JPEG,
+    CAIRO_MIME_TYPE_PNG,
+    CAIRO_MIME_TYPE_JP2,
+    CAIRO_MIME_TYPE_JBIG2,
+    CAIRO_MIME_TYPE_CCITT_FAX,
+};
+
+cairo_bool_t
+_cairo_surface_has_mime_image (cairo_surface_t *surface)
+{
+    cairo_user_data_slot_t *slots;
+    int i, j, num_slots;
+
+    /* Prevent reads of the array during teardown */
+    if (! CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&surface->ref_count))
+	return FALSE;
+
+    /* The number of mime-types attached to a surface is usually small,
+     * typically zero. Therefore it is quicker to do a strcmp() against
+     * each key than it is to intern the string (i.e. compute a hash,
+     * search the hash table, and do a final strcmp).
+     */
+    num_slots = surface->mime_data.num_elements;
+    slots = _cairo_array_index (&surface->mime_data, 0);
+    for (i = 0; i < num_slots; i++) {
+	if (slots[i].key != NULL) {
+	    for (j = 0; j < ARRAY_LENGTH (_cairo_surface_image_mime_types); j++) {
+		if (strcmp ((char *) slots[i].key, _cairo_surface_image_mime_types[j]) == 0)
+		    return TRUE;
+	    }
+	}
+    }
+
+    return FALSE;
+}
+
 /**
+ * CAIRO_MIME_TYPE_CCITT_FAX:
+ *
+ * Group 3 or Group 4 CCITT facsimile encoding (International
+ * Telecommunication Union, Recommendations T.4 and T.6.)
+ *
+ * Since: 1.16
+ **/
+
+/**
+ * CAIRO_MIME_TYPE_CCITT_FAX_PARAMS:
+ *
+ * Decode parameters for Group 3 or Group 4 CCITT facsimile encoding.
+ * See [CCITT Fax Images][ccitt].
+ *
+ * Since: 1.16
+ **/
+
+/**
+ * CAIRO_MIME_TYPE_EPS:
+ *
+ * Encapsulated PostScript file.
+ * [Encapsulated PostScript File Format Specification](http://wwwimages.adobe.com/content/dam/Adobe/endevnet/postscript/pdfs/5002.EPSF_Spec.pdf)
+ *
+ * Since: 1.16
+ **/
+
+/**
+ * CAIRO_MIME_TYPE_EPS_PARAMS:
+ *
+ * Embedding parameters Encapsulated PostScript data.
+ * See [Embedding EPS files][eps].
+ *
+ * Since: 1.16
+ **/
+
+/**
  * CAIRO_MIME_TYPE_JBIG2:
  *
  * Joint Bi-level Image Experts Group image coding standard (ISO/IEC 11544).
@@ -1315,7 +1388,8 @@
  * The recognized MIME types are the following: %CAIRO_MIME_TYPE_JPEG,
  * %CAIRO_MIME_TYPE_PNG, %CAIRO_MIME_TYPE_JP2, %CAIRO_MIME_TYPE_URI,
  * %CAIRO_MIME_TYPE_UNIQUE_ID, %CAIRO_MIME_TYPE_JBIG2,
- * %CAIRO_MIME_TYPE_JBIG2_GLOBAL, %CAIRO_MIME_TYPE_JBIG2_GLOBAL_ID.
+ * %CAIRO_MIME_TYPE_JBIG2_GLOBAL, %CAIRO_MIME_TYPE_JBIG2_GLOBAL_ID,
+ * %CAIRO_MIME_TYPE_CCITT_FAX, %CAIRO_MIME_TYPE_CCITT_FAX_PARAMS.
  *
  * See corresponding backend surface docs for details about which MIME
  * types it can handle. Caution: the associated MIME data will be
@@ -1364,7 +1438,7 @@
 	return _cairo_surface_set_error (surface, status);
 
     if (data != NULL) {
-	mime_data = malloc (sizeof (cairo_mime_data_t));
+	mime_data = _cairo_malloc (sizeof (cairo_mime_data_t));
 	if (unlikely (mime_data == NULL))
 	    return _cairo_surface_set_error (surface, _cairo_error (CAIRO_STATUS_NO_MEMORY));
 
@@ -1387,6 +1461,8 @@
 	return _cairo_surface_set_error (surface, status);
     }
 
+    surface->is_clear = FALSE;
+
     return CAIRO_STATUS_SUCCESS;
 }
 slim_hidden_def (cairo_surface_set_mime_data);
@@ -1461,6 +1537,8 @@
 				    _cairo_mime_data_reference,
 				    NULL);
 
+    dst->is_clear = FALSE;
+
     return CAIRO_STATUS_SUCCESS;
 }
 
@@ -2518,6 +2596,200 @@
 }
 slim_hidden_def (cairo_surface_has_show_text_glyphs);
 
+#define GLYPH_CACHE_SIZE 64
+
+static inline cairo_int_status_t
+ensure_scaled_glyph (cairo_scaled_font_t   *scaled_font,
+                     cairo_scaled_glyph_t **glyph_cache,
+                     cairo_glyph_t         *glyph,
+                     cairo_scaled_glyph_t **scaled_glyph)
+{
+    int cache_index;
+    cairo_int_status_t status = CAIRO_INT_STATUS_SUCCESS;
+
+    cache_index = glyph->index % GLYPH_CACHE_SIZE;
+    *scaled_glyph = glyph_cache[cache_index];
+    if (*scaled_glyph == NULL || _cairo_scaled_glyph_index (*scaled_glyph) != glyph->index) {
+        status = _cairo_scaled_glyph_lookup (scaled_font,
+                                             glyph->index,
+                                             CAIRO_SCALED_GLYPH_INFO_SURFACE,
+                                             scaled_glyph);
+        if (unlikely (status))
+            status = _cairo_scaled_font_set_error (scaled_font, status);
+
+        glyph_cache[cache_index] = *scaled_glyph;
+    }
+
+    return status;
+}
+
+static inline cairo_int_status_t
+composite_one_color_glyph (cairo_surface_t       *surface,
+                           cairo_operator_t       op,
+                           const cairo_pattern_t *source,
+                           const cairo_clip_t    *clip,
+                           cairo_glyph_t         *glyph,
+                           cairo_scaled_glyph_t  *scaled_glyph)
+{
+    cairo_int_status_t status;
+    cairo_image_surface_t *glyph_surface;
+    cairo_pattern_t *pattern;
+    cairo_matrix_t matrix;
+
+    status = CAIRO_INT_STATUS_SUCCESS;
+
+    glyph_surface = scaled_glyph->color_surface;
+
+    if (glyph_surface->width && glyph_surface->height) {
+        int x, y;
+        /* round glyph locations to the nearest pixels */
+        /* XXX: FRAGILE: We're ignoring device_transform scaling here. A bug? */
+	x = _cairo_lround (glyph->x - glyph_surface->base.device_transform.x0);
+	y = _cairo_lround (glyph->y - glyph_surface->base.device_transform.y0);
+
+        pattern = cairo_pattern_create_for_surface ((cairo_surface_t *)glyph_surface);
+        cairo_matrix_init_translate (&matrix, - x, - y);
+        cairo_pattern_set_matrix (pattern, &matrix);
+	if (op == CAIRO_OPERATOR_SOURCE || op == CAIRO_OPERATOR_CLEAR)
+	  status = surface->backend->mask (surface, op, pattern, pattern, clip);
+	else
+	  status = surface->backend->paint (surface, op, pattern, clip);
+        cairo_pattern_destroy (pattern);
+    }
+
+    return status;
+}
+
+static cairo_int_status_t
+composite_color_glyphs (cairo_surface_t             *surface,
+                        cairo_operator_t             op,
+                        const cairo_pattern_t       *source,
+                        char                        *utf8,
+                        int                         *utf8_len,
+                        cairo_glyph_t               *glyphs,
+                        int                         *num_glyphs,
+                        cairo_text_cluster_t        *clusters,
+	                int			    *num_clusters,
+		        cairo_text_cluster_flags_t   cluster_flags,
+                        cairo_scaled_font_t         *scaled_font,
+                        const cairo_clip_t          *clip)
+{
+    cairo_int_status_t status;
+    int i, j;
+    cairo_scaled_glyph_t *scaled_glyph;
+    int remaining_clusters = 0;
+    int remaining_glyphs = 0;
+    int remaining_bytes = 0;
+    int glyph_pos = 0;
+    int byte_pos = 0;
+    int gp;
+    cairo_scaled_glyph_t *glyph_cache[GLYPH_CACHE_SIZE];
+
+    memset (glyph_cache, 0, sizeof (glyph_cache));
+
+    status = CAIRO_INT_STATUS_SUCCESS;
+
+    _cairo_scaled_font_freeze_cache (scaled_font);
+
+    if (clusters) {
+
+        if (cluster_flags & CAIRO_TEXT_CLUSTER_FLAG_BACKWARD)
+            glyph_pos = *num_glyphs - 1;
+
+        for (i = 0; i < *num_clusters; i++) {
+            cairo_bool_t skip_cluster = FALSE;
+
+            for (j = 0; j < clusters[i].num_glyphs; j++) {
+                if (cluster_flags & CAIRO_TEXT_CLUSTER_FLAG_BACKWARD)
+                    gp = glyph_pos - j;
+                else
+                    gp = glyph_pos + j;
+
+                status = ensure_scaled_glyph (scaled_font, glyph_cache,
+                                              &glyphs[gp], &scaled_glyph);
+                if (unlikely (status))
+                    goto UNLOCK;
+
+                if ((scaled_glyph->has_info & CAIRO_SCALED_GLYPH_INFO_COLOR_SURFACE) == 0) {
+                    skip_cluster = TRUE;
+                    break;
+                }
+            }
+
+            if (skip_cluster) {
+                memmove (utf8 + remaining_bytes, utf8 + byte_pos, clusters[i].num_bytes);
+                remaining_bytes += clusters[i].num_bytes;
+                byte_pos += clusters[i].num_bytes;
+                for (j = 0; j < clusters[i].num_glyphs; j++, remaining_glyphs++) {
+                    if (cluster_flags & CAIRO_TEXT_CLUSTER_FLAG_BACKWARD)
+                        glyphs[*num_glyphs - 1 - remaining_glyphs] = glyphs[glyph_pos--];
+                    else
+                        glyphs[remaining_glyphs] = glyphs[glyph_pos++];
+                }
+                clusters[remaining_clusters++] = clusters[i];
+                continue;
+            }
+
+            for (j = 0; j < clusters[i].num_glyphs; j++) {
+                if (cluster_flags & CAIRO_TEXT_CLUSTER_FLAG_BACKWARD)
+                    gp = glyph_pos - j;
+                else
+                    gp = glyph_pos + j;
+
+                status = ensure_scaled_glyph (scaled_font, glyph_cache,
+                                              &glyphs[gp], &scaled_glyph);
+                if (unlikely (status))
+                    goto UNLOCK;
+
+                status = composite_one_color_glyph (surface, op, source, clip,
+                                                    &glyphs[gp], scaled_glyph);
+                if (unlikely (status && status != CAIRO_INT_STATUS_NOTHING_TO_DO))
+                    goto UNLOCK;
+            }
+
+            if (cluster_flags & CAIRO_TEXT_CLUSTER_FLAG_BACKWARD)
+                glyph_pos -= clusters[i].num_glyphs;
+            else
+                glyph_pos += clusters[i].num_glyphs;
+
+            byte_pos += clusters[i].num_bytes;
+        }
+
+        if (cluster_flags & CAIRO_TEXT_CLUSTER_FLAG_BACKWARD)
+            memmove (utf8, utf8 + *utf8_len - remaining_bytes, remaining_bytes);
+
+        *utf8_len = remaining_bytes;
+        *num_glyphs = remaining_glyphs;
+        *num_clusters = remaining_clusters;
+
+    } else {
+
+       for (glyph_pos = 0; glyph_pos < *num_glyphs; glyph_pos++) {
+           status = ensure_scaled_glyph (scaled_font, glyph_cache,
+                                         &glyphs[glyph_pos], &scaled_glyph);
+           if (unlikely (status))
+               goto UNLOCK;
+
+           if ((scaled_glyph->has_info & CAIRO_SCALED_GLYPH_INFO_COLOR_SURFACE) == 0) {
+               glyphs[remaining_glyphs++] = glyphs[glyph_pos];
+               continue;
+           }
+
+           status = composite_one_color_glyph (surface, op, source, clip,
+                                               &glyphs[glyph_pos], scaled_glyph);
+           if (unlikely (status && status != CAIRO_INT_STATUS_NOTHING_TO_DO))
+               goto UNLOCK;
+        }
+
+        *num_glyphs = remaining_glyphs;
+    }
+
+UNLOCK:
+    _cairo_scaled_font_thaw_cache (scaled_font);
+
+    return status;
+}
+
 /* Note: the backends may modify the contents of the glyph array as long as
  * they do not return %CAIRO_INT_STATUS_UNSUPPORTED. This makes it possible to
  * avoid copying the array again and again, and edit it in-place.
@@ -2574,6 +2846,22 @@
 
     status = CAIRO_INT_STATUS_UNSUPPORTED;
 
+    if (_cairo_scaled_font_has_color_glyphs (scaled_font)) {
+        status = composite_color_glyphs (surface, op,
+                                         source,
+                                         (char *)utf8, &utf8_len,
+                                         glyphs, &num_glyphs,
+                                         (cairo_text_cluster_t *)clusters, &num_clusters, cluster_flags,
+                                         scaled_font,
+                                         clip);
+
+        if (unlikely (status && status != CAIRO_INT_STATUS_NOTHING_TO_DO))
+            goto DONE;
+
+        if (num_glyphs == 0)
+            goto DONE;
+    }
+
     /* The logic here is duplicated in _cairo_analysis_surface show_glyphs and
      * show_text_glyphs.  Keep in synch. */
     if (clusters) {
@@ -2624,6 +2912,7 @@
 	}
     }
 
+DONE:
     if (status != CAIRO_INT_STATUS_NOTHING_TO_DO) {
 	surface->is_clear = FALSE;
 	surface->serial++;
@@ -2632,6 +2921,42 @@
     return _cairo_surface_set_error (surface, status);
 }
 
+cairo_status_t
+_cairo_surface_tag (cairo_surface_t	        *surface,
+		    cairo_bool_t                 begin,
+		    const char                  *tag_name,
+		    const char                  *attributes,
+		    const cairo_pattern_t	*source,
+		    const cairo_stroke_style_t	*stroke_style,
+		    const cairo_matrix_t	*ctm,
+		    const cairo_matrix_t	*ctm_inverse,
+		    const cairo_clip_t	        *clip)
+{
+    cairo_int_status_t status;
+
+    TRACE ((stderr, "%s\n", __FUNCTION__));
+    if (unlikely (surface->status))
+	return surface->status;
+    if (unlikely (surface->finished))
+	return _cairo_surface_set_error (surface, _cairo_error (CAIRO_STATUS_SURFACE_FINISHED));
+
+    if (surface->backend->tag == NULL)
+	return CAIRO_STATUS_SUCCESS;
+
+    if (begin) {
+	status = _pattern_has_error (source);
+	if (unlikely (status))
+	    return status;
+    }
+
+    status = surface->backend->tag (surface, begin, tag_name, attributes,
+				    source, stroke_style,
+				    ctm, ctm_inverse, clip);
+
+    return _cairo_surface_set_error (surface, status);
+}
+
+
 /**
  * _cairo_surface_set_resolution:
  * @surface: the surface
@@ -2725,6 +3050,10 @@
     case CAIRO_STATUS_INVALID_MESH_CONSTRUCTION:
     case CAIRO_STATUS_DEVICE_FINISHED:
     case CAIRO_STATUS_JBIG2_GLOBAL_MISSING:
+    case CAIRO_STATUS_PNG_ERROR:
+    case CAIRO_STATUS_FREETYPE_ERROR:
+    case CAIRO_STATUS_WIN32_GDI_ERROR:
+    case CAIRO_STATUS_TAG_ERROR:
     default:
 	_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
 	return (cairo_surface_t *) &_cairo_surface_nil;

Modified: trunk/Build/source/libs/cairo/cairo-src/src/cairo-svg-surface-private.h
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/src/cairo-svg-surface-private.h	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/src/cairo-svg-surface-private.h	2018-10-20 03:19:36 UTC (rev 48952)
@@ -48,6 +48,13 @@
 
 typedef struct cairo_svg_document cairo_svg_document_t;
 
+typedef struct _cairo_svg_source_surface {
+    cairo_hash_entry_t base;
+    unsigned int id;
+    unsigned char *unique_id;
+    unsigned long unique_id_length;
+} cairo_svg_source_surface_t;
+
 typedef struct cairo_svg_surface {
     cairo_surface_t base;
 
@@ -55,11 +62,13 @@
 
     double width;
     double height;
+    cairo_bool_t surface_bounded;
 
     cairo_svg_document_t *document;
 
     cairo_output_stream_t *xml_node;
     cairo_array_t	   page_set;
+    cairo_hash_table_t    *source_surfaces;
 
     cairo_surface_clipper_t clipper;
     unsigned int clip_level;

Modified: trunk/Build/source/libs/cairo/cairo-src/src/cairo-svg-surface.c
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/src/cairo-svg-surface.c	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/src/cairo-svg-surface.c	2018-10-20 03:19:36 UTC (rev 48952)
@@ -94,6 +94,7 @@
 {
     CAIRO_MIME_TYPE_JPEG,
     CAIRO_MIME_TYPE_PNG,
+    CAIRO_MIME_TYPE_UNIQUE_ID,
     CAIRO_MIME_TYPE_URI,
     NULL
 };
@@ -121,6 +122,20 @@
     "1.2"
 };
 
+static const char * _cairo_svg_unit_strings[] =
+{
+    "",
+    "em",
+    "ex",
+    "px",
+    "in",
+    "cm",
+    "mm",
+    "pt",
+    "pc",
+    "%"
+};
+
 struct cairo_svg_page {
     unsigned int surface_id;
     unsigned int clip_level;
@@ -135,6 +150,7 @@
 
     double width;
     double height;
+    cairo_svg_unit_t unit;
 
     cairo_output_stream_t *xml_node_defs;
     cairo_output_stream_t *xml_node_glyphs;
@@ -176,7 +192,9 @@
 _cairo_svg_surface_create_for_document (cairo_svg_document_t	*document,
 					cairo_content_t		 content,
 					double			 width,
-					double			 height);
+					double			 height,
+					cairo_bool_t             bounded);
+
 static cairo_surface_t *
 _cairo_svg_surface_create_for_stream_internal (cairo_output_stream_t	*stream,
 					       double			 width,
@@ -252,6 +270,9 @@
  * or %CAIRO_MIME_TYPE_PNG is specified, the corresponding data is
  * Base64-encoded and emitted.
  *
+ * If %CAIRO_MIME_TYPE_UNIQUE_ID is present, all surfaces with the same
+ * unique identifier will only be embedded once.
+ *
  * Return value: a pointer to the newly created surface. The caller
  * owns the surface and should call cairo_surface_destroy() when done
  * with it.
@@ -399,7 +420,165 @@
     return _cairo_svg_version_strings[version];
 }
 
+/**
+ * cairo_svg_surface_set_document_unit:
+ * @surface: a SVG #cairo_surface_t
+ * @unit: SVG unit
+ *
+ * Use the specified unit for the width and height of the generated SVG file.
+ * See #cairo_svg_unit_t for a list of available unit values that can be used
+ * here.
+ *
+ * This function can be called at any time before generating the SVG file.
+ *
+ * However to minimize the risk of ambiguities it's recommended to call it
+ * before any drawing operations have been performed on the given surface, to
+ * make it clearer what the unit used in the drawing operations is.
+ *
+ * The simplest way to do this is to call this function immediately after
+ * creating the SVG surface.
+ *
+ * Note if this function is never called, the default unit for SVG documents
+ * generated by cairo will be "pt". This is for historical reasons.
+ *
+ * Since: 1.16
+ **/
+void
+cairo_svg_surface_set_document_unit (cairo_surface_t	*abstract_surface,
+				     cairo_svg_unit_t	 unit)
+{
+    cairo_svg_surface_t *surface = NULL; /* hide compiler warning */
+
+    if (! _extract_svg_surface (abstract_surface, &surface))
+	return;
+
+    if (unit <= CAIRO_SVG_UNIT_PERCENT)
+	surface->document->unit = unit;
+}
+
+/**
+ * cairo_svg_surface_get_document_unit:
+ * @surface: a SVG #cairo_surface_t
+ *
+ * Get the unit of the SVG surface.
+ *
+ * If the surface passed as an argument is not a SVG surface, the function
+ * sets the error status to CAIRO_STATUS_SURFACE_TYPE_MISMATCH and returns
+ * CAIRO_SVG_UNIT_USER.
+ *
+ * Return value: the SVG unit of the SVG surface.
+ *
+ * Since: 1.16
+ **/
+cairo_svg_unit_t
+cairo_svg_surface_get_document_unit (cairo_surface_t	*abstract_surface)
+{
+    cairo_svg_surface_t *surface = NULL; /* hide compiler warning */
+
+    if (! _extract_svg_surface (abstract_surface, &surface)) {
+	_cairo_error_throw (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
+	return CAIRO_SVG_UNIT_USER;
+    }
+
+    return surface->document->unit;
+}
+
+static void
+_cairo_svg_source_surface_init_key (cairo_svg_source_surface_t *key)
+{
+    if (key->unique_id && key->unique_id_length > 0) {
+	key->base.hash = _cairo_hash_bytes (_CAIRO_HASH_INIT_VALUE,
+					    key->unique_id, key->unique_id_length);
+    } else {
+	key->base.hash = key->id;
+    }
+}
+
 static cairo_bool_t
+_cairo_svg_source_surface_equal (const void *key_a, const void *key_b)
+{
+    const cairo_svg_source_surface_t *a = key_a;
+    const cairo_svg_source_surface_t *b = key_b;
+
+    if (a->unique_id && b->unique_id && a->unique_id_length == b->unique_id_length)
+	return (memcmp (a->unique_id, b->unique_id, a->unique_id_length) == 0);
+
+    return (a->id == b->id);
+}
+
+static void
+_cairo_svg_source_surface_pluck (void *entry, void *closure)
+{
+    cairo_svg_source_surface_t *surface_entry = entry;
+    cairo_hash_table_t *patterns = closure;
+
+    _cairo_hash_table_remove (patterns, &surface_entry->base);
+    free (surface_entry->unique_id);
+    free (surface_entry);
+}
+
+static cairo_status_t
+_cairo_svg_surface_add_source_surface (cairo_svg_surface_t  *surface,
+				       cairo_surface_t	    *source_surface,
+				       int                  *source_id,
+				       cairo_bool_t         *is_new)
+{
+    cairo_svg_source_surface_t source_key;
+    cairo_svg_source_surface_t *source_entry;
+    unsigned char *unique_id = NULL;
+    unsigned long unique_id_length = 0;
+    cairo_status_t status;
+
+    source_key.id  = source_surface->unique_id;
+    cairo_surface_get_mime_data (source_surface, CAIRO_MIME_TYPE_UNIQUE_ID,
+				 (const unsigned char **) &source_key.unique_id,
+				 &source_key.unique_id_length);
+    _cairo_svg_source_surface_init_key (&source_key);
+    source_entry = _cairo_hash_table_lookup (surface->source_surfaces, &source_key.base);
+    if (source_entry) {
+	*source_id = source_entry->id;
+	*is_new = FALSE;
+	return CAIRO_STATUS_SUCCESS;
+    }
+
+    if (source_key.unique_id && source_key.unique_id_length > 0) {
+	unique_id = _cairo_malloc (source_key.unique_id_length);
+	if (unique_id == NULL) {
+	    return _cairo_error (CAIRO_STATUS_NO_MEMORY);
+	}
+
+	unique_id_length = source_key.unique_id_length;
+	memcpy (unique_id, source_key.unique_id, unique_id_length);
+    } else {
+	unique_id = NULL;
+	unique_id_length = 0;
+    }
+
+    source_entry = malloc (sizeof (cairo_svg_source_surface_t));
+    if (source_entry == NULL) {
+	status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
+	goto fail;
+    }
+
+    source_entry->id = source_key.id;
+    source_entry->unique_id_length = unique_id_length;
+    source_entry->unique_id = unique_id;
+    _cairo_svg_source_surface_init_key (source_entry);
+    status = _cairo_hash_table_insert (surface->source_surfaces, &source_entry->base);
+    if (unlikely(status))
+	goto fail;
+
+    *is_new = TRUE;
+    *source_id = source_entry->id;
+    return CAIRO_STATUS_SUCCESS;
+
+  fail:
+    free (unique_id);
+    free (source_entry);
+    return status;
+}
+
+static cairo_bool_t
 _cliprect_covers_surface (cairo_svg_surface_t *surface,
 			  cairo_path_fixed_t *path)
 {
@@ -470,13 +649,14 @@
 _cairo_svg_surface_create_for_document (cairo_svg_document_t	*document,
 					cairo_content_t		 content,
 					double			 width,
-					double			 height)
+					double			 height,
+					cairo_bool_t             bounded)
 {
     cairo_svg_surface_t *surface;
     cairo_surface_t *paginated;
     cairo_status_t status, status_ignored;
 
-    surface = malloc (sizeof (cairo_svg_surface_t));
+    surface = _cairo_malloc (sizeof (cairo_svg_surface_t));
     if (unlikely (surface == NULL))
 	return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
 
@@ -483,10 +663,12 @@
     _cairo_surface_init (&surface->base,
 			 &cairo_svg_surface_backend,
 			 NULL, /* device */
-			 content);
+			 content,
+			 TRUE); /* is_vector */
 
     surface->width = width;
     surface->height = height;
+    surface->surface_bounded = bounded;
 
     surface->document = _cairo_svg_document_reference (document);
 
@@ -519,6 +701,12 @@
     surface->force_fallbacks = FALSE;
     surface->content = content;
 
+    surface->source_surfaces = _cairo_hash_table_create (_cairo_svg_source_surface_equal);
+    if (unlikely (surface->source_surfaces == NULL)) {
+	status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
+	goto CLEANUP;
+    }
+
     paginated = _cairo_paginated_surface_create (&surface->base,
 					         surface->content,
 						 &cairo_svg_surface_paginated_backend);
@@ -560,7 +748,7 @@
     }
 
     surface = _cairo_svg_surface_create_for_document (document, CAIRO_CONTENT_COLOR_ALPHA,
-						      width, height);
+						      width, height, TRUE);
     if (surface->status) {
 	status = _cairo_svg_document_destroy (document);
 	return surface;
@@ -1010,6 +1198,11 @@
 
     _cairo_surface_clipper_reset (&surface->clipper);
 
+    _cairo_hash_table_foreach (surface->source_surfaces,
+			       _cairo_svg_source_surface_pluck,
+			       surface->source_surfaces);
+    _cairo_hash_table_destroy (surface->source_surfaces);
+
     status2 = _cairo_svg_document_destroy (document);
     if (status == CAIRO_STATUS_SUCCESS)
 	status = status2;
@@ -1281,7 +1474,8 @@
 
 static cairo_status_t
 _cairo_svg_surface_emit_surface (cairo_svg_document_t *document,
-				 cairo_surface_t *surface)
+				 cairo_surface_t *surface,
+				 int source_id)
 {
     cairo_rectangle_int_t extents;
     cairo_bool_t is_bounded;
@@ -1289,18 +1483,12 @@
     const unsigned char *uri;
     unsigned long uri_len;
 
-    if (_cairo_user_data_array_get_data (&surface->user_data,
-					 (cairo_user_data_key_t *) document))
-    {
-	return CAIRO_STATUS_SUCCESS;
-    }
-
     is_bounded = _cairo_surface_get_extents (surface, &extents);
     assert (is_bounded);
 
     _cairo_output_stream_printf (document->xml_node_defs,
 				 "<image id=\"image%d\" width=\"%d\" height=\"%d\"",
-				 surface->unique_id,
+				 source_id,
 				 extents.width, extents.height);
 
     _cairo_output_stream_printf (document->xml_node_defs, " xlink:href=\"");
@@ -1319,10 +1507,7 @@
 
     _cairo_output_stream_printf (document->xml_node_defs, "\"/>\n");
 
-    /* and tag it */
-    return _cairo_user_data_array_set_data (&surface->user_data,
-					    (cairo_user_data_key_t *) document,
-					    document, NULL);
+    return CAIRO_STATUS_SUCCESS;
 }
 
 static cairo_status_t
@@ -1336,6 +1521,8 @@
 {
     cairo_status_t status;
     cairo_matrix_t p2u;
+    int source_id;
+    cairo_bool_t is_new;
 
     p2u = pattern->base.matrix;
     status = cairo_matrix_invert (&p2u);
@@ -1342,11 +1529,21 @@
     /* cairo_pattern_set_matrix ensures the matrix is invertible */
     assert (status == CAIRO_STATUS_SUCCESS);
 
-    status = _cairo_svg_surface_emit_surface (svg_surface->document,
-					      pattern->surface);
+    status = _cairo_svg_surface_add_source_surface (svg_surface,
+						    pattern->surface,
+						    &source_id,
+						    &is_new);
     if (unlikely (status))
 	return status;
 
+    if (is_new) {
+	status = _cairo_svg_surface_emit_surface (svg_surface->document,
+						  pattern->surface,
+						  source_id);
+	if (unlikely (status))
+	    return status;
+    }
+
     if (pattern_id != invalid_pattern_id) {
 	cairo_rectangle_int_t extents;
 	cairo_bool_t is_bounded;
@@ -1368,7 +1565,7 @@
 
     _cairo_output_stream_printf (output,
 				 "<use xlink:href=\"#image%d\"",
-				 pattern->surface->unique_id);
+				 source_id);
     if (extra_attributes)
 	_cairo_output_stream_printf (output, " %s", extra_attributes);
 
@@ -1389,25 +1586,23 @@
 
 static cairo_status_t
 _cairo_svg_surface_emit_recording_surface (cairo_svg_document_t      *document,
-					   cairo_recording_surface_t *source)
+					   cairo_recording_surface_t *source,
+					   int                        source_id)
 {
     cairo_status_t status;
     cairo_surface_t *paginated_surface;
     cairo_svg_surface_t *svg_surface;
     cairo_array_t *page_set;
-
+    cairo_rectangle_int_t extents;
+    cairo_bool_t bounded;
     cairo_output_stream_t *contents;
 
-    if (_cairo_user_data_array_get_data (&source->base.user_data,
-					 (cairo_user_data_key_t *) document))
-    {
-	return CAIRO_STATUS_SUCCESS;
-    }
-
+    bounded = _cairo_surface_get_extents (&source->base, &extents);
     paginated_surface = _cairo_svg_surface_create_for_document (document,
 								source->base.content,
-								source->extents_pixels.width,
-								source->extents_pixels.height);
+								extents.width,
+								extents.height,
+								bounded);
     if (unlikely (paginated_surface->status))
 	return paginated_surface->status;
 
@@ -1435,13 +1630,17 @@
 
     if (! svg_surface->is_base_clip_emitted) {
 	svg_surface->is_base_clip_emitted = TRUE;
-	_cairo_output_stream_printf (document->xml_node_defs,
-				     "<clipPath id=\"clip%d\">\n"
-				     "  <rect width=\"%f\" height=\"%f\"/>\n"
-				     "</clipPath>\n",
-				     svg_surface->base_clip,
-				     svg_surface->width,
-				     svg_surface->height);
+	if (_cairo_surface_get_extents (&svg_surface->base, &extents)) {
+	    _cairo_output_stream_printf (document->xml_node_defs,
+					 "<clipPath id=\"clip%d\">\n"
+					 "  <rect x=\"%d\" y=\"%d\" width=\"%d\" height=\"%d\"/>\n"
+					 "</clipPath>\n",
+					 svg_surface->base_clip,
+					 extents.x,
+					 extents.y,
+					 extents.width,
+					 extents.height);
+	}
     }
 
     if (source->base.content == CAIRO_CONTENT_ALPHA) {
@@ -1450,13 +1649,13 @@
 				     "<g id=\"surface%d\" "
 				     "clip-path=\"url(#clip%d)\" "
 				     "filter=\"url(#alpha)\">\n",
-				     source->base.unique_id,
+				     source_id,
 				     svg_surface->base_clip);
     } else {
 	_cairo_output_stream_printf (document->xml_node_defs,
 				     "<g id=\"surface%d\" "
 				     "clip-path=\"url(#clip%d)\">\n",
-				     source->base.unique_id,
+				     source_id,
 				     svg_surface->base_clip);
     }
 
@@ -1482,13 +1681,7 @@
     status = cairo_surface_status (paginated_surface);
     cairo_surface_destroy (paginated_surface);
 
-    if (unlikely (status))
-	return status;
-
-    /* and tag it */
-    return _cairo_user_data_array_set_data (&source->base.user_data,
-					    (cairo_user_data_key_t *) document,
-					    document, NULL);
+    return status;
 }
 
 static cairo_recording_surface_t *
@@ -1515,6 +1708,8 @@
     cairo_recording_surface_t *recording_surface;
     cairo_matrix_t p2u;
     cairo_status_t status;
+    int source_id;
+    cairo_bool_t is_new;
 
     p2u = pattern->base.matrix;
     status = cairo_matrix_invert (&p2u);
@@ -1521,11 +1716,20 @@
     /* cairo_pattern_set_matrix ensures the matrix is invertible */
     assert (status == CAIRO_STATUS_SUCCESS);
 
-    recording_surface = to_recording_surface (pattern);
-    status = _cairo_svg_surface_emit_recording_surface (document, recording_surface);
+    status = _cairo_svg_surface_add_source_surface (surface,
+						    pattern->surface,
+						    &source_id,
+						    &is_new);
     if (unlikely (status))
 	return status;
 
+    recording_surface = to_recording_surface (pattern);
+    if (is_new) {
+	status = _cairo_svg_surface_emit_recording_surface (document, recording_surface, source_id);
+	if (unlikely (status))
+	    return status;
+    }
+
     if (pattern_id != invalid_pattern_id) {
 	_cairo_output_stream_printf (output,
 				     "<pattern id=\"pattern%d\" "
@@ -1540,7 +1744,7 @@
 
     _cairo_output_stream_printf (output,
 				 "<use xlink:href=\"#surface%d\"",
-				 recording_surface->base.unique_id);
+				 source_id);
 
     if (pattern_id == invalid_pattern_id) {
 	_cairo_svg_surface_emit_operator (output, surface, op);
@@ -2257,7 +2461,7 @@
     rectangle->width  = ceil (surface->width);
     rectangle->height = ceil (surface->height);
 
-    return TRUE;
+    return surface->surface_bounded;
 }
 
 static cairo_status_t
@@ -2658,7 +2862,7 @@
     if (output_stream->status)
 	return output_stream->status;
 
-    document = malloc (sizeof (cairo_svg_document_t));
+    document = _cairo_malloc (sizeof (cairo_svg_document_t));
     if (unlikely (document == NULL))
 	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
@@ -2675,6 +2879,7 @@
     document->finished = FALSE;
     document->width = width;
     document->height = height;
+    document->unit = CAIRO_SVG_UNIT_PT;
 
     document->linear_pattern_id = 0;
     document->radial_pattern_id = 0;
@@ -2777,10 +2982,11 @@
 				 "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
 				 "<svg xmlns=\"http://www.w3.org/2000/svg\" "
 				 "xmlns:xlink=\"http://www.w3.org/1999/xlink\" "
-				 "width=\"%fpt\" height=\"%fpt\" "
+				 "width=\"%f%s\" height=\"%f%s\" "
 				 "viewBox=\"0 0 %f %f\" version=\"%s\">\n",
+				 document->width, _cairo_svg_unit_strings [document->unit],
+				 document->height, _cairo_svg_unit_strings [document->unit],
 				 document->width, document->height,
-				 document->width, document->height,
 				 _cairo_svg_internal_version_strings [document->svg_version]);
 
     status = _cairo_svg_document_emit_font_subsets (document);
@@ -2851,7 +3057,7 @@
     return status;
 }
 
-static void
+static cairo_int_status_t
 _cairo_svg_surface_set_paginated_mode (void			*abstract_surface,
 				       cairo_paginated_mode_t	 paginated_mode)
 {
@@ -2858,6 +3064,8 @@
     cairo_svg_surface_t *surface = abstract_surface;
 
     surface->paginated_mode = paginated_mode;
+
+    return CAIRO_STATUS_SUCCESS;
 }
 
 static cairo_bool_t

Modified: trunk/Build/source/libs/cairo/cairo-src/src/cairo-svg.h
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/src/cairo-svg.h	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/src/cairo-svg.h	2018-10-20 03:19:36 UTC (rev 48952)
@@ -53,6 +53,46 @@
     CAIRO_SVG_VERSION_1_2
 } cairo_svg_version_t;
 
+/**
+ * cairo_svg_unit_t:
+ *
+ * @CAIRO_SVG_UNIT_USER: User unit, a value in the current coordinate system.
+ *   If used in the root element for the initial coordinate systems it
+ *   corresponds to pixels. (Since 1.16)
+ * @CAIRO_SVG_UNIT_EM: The size of the element's font. (Since 1.16)
+ * @CAIRO_SVG_UNIT_EX: The x-height of the element’s font. (Since 1.16)
+ * @CAIRO_SVG_UNIT_PX: Pixels (1px = 1/96th of 1in). (Since 1.16)
+ * @CAIRO_SVG_UNIT_IN: Inches (1in = 2.54cm = 96px). (Since 1.16)
+ * @CAIRO_SVG_UNIT_CM: Centimeters (1cm = 96px/2.54). (Since 1.16)
+ * @CAIRO_SVG_UNIT_MM: Millimeters (1mm = 1/10th of 1cm). (Since 1.16)
+ * @CAIRO_SVG_UNIT_PT: Points (1pt = 1/72th of 1in). (Since 1.16)
+ * @CAIRO_SVG_UNIT_PC: Picas (1pc = 1/6th of 1in). (Since 1.16)
+ * @CAIRO_SVG_UNIT_PERCENT: Percent, a value that is some fraction of another
+ *   reference value. (Since 1.16)
+ *
+ * #cairo_svg_unit_t is used to describe the units valid for coordinates and
+ * lengths in the SVG specification.
+ *
+ * See also:
+ * https://www.w3.org/TR/SVG/coords.html#Units
+ * https://www.w3.org/TR/SVG/types.html#DataTypeLength
+ * https://www.w3.org/TR/css-values-3/#lengths
+ *
+ * Since: 1.16
+ **/
+typedef enum _cairo_svg_unit {
+    CAIRO_SVG_UNIT_USER = 0,
+    CAIRO_SVG_UNIT_EM,
+    CAIRO_SVG_UNIT_EX,
+    CAIRO_SVG_UNIT_PX,
+    CAIRO_SVG_UNIT_IN,
+    CAIRO_SVG_UNIT_CM,
+    CAIRO_SVG_UNIT_MM,
+    CAIRO_SVG_UNIT_PT,
+    CAIRO_SVG_UNIT_PC,
+    CAIRO_SVG_UNIT_PERCENT
+} cairo_svg_unit_t;
+
 cairo_public cairo_surface_t *
 cairo_svg_surface_create (const char   *filename,
 			  double	width_in_points,
@@ -75,6 +115,13 @@
 cairo_public const char *
 cairo_svg_version_to_string (cairo_svg_version_t version);
 
+cairo_public void
+cairo_svg_surface_set_document_unit (cairo_surface_t	*surface,
+				     cairo_svg_unit_t	 unit);
+
+cairo_public cairo_svg_unit_t
+cairo_svg_surface_get_document_unit (cairo_surface_t	*surface);
+
 CAIRO_END_DECLS
 
 #else  /* CAIRO_HAS_SVG_SURFACE */

Added: trunk/Build/source/libs/cairo/cairo-src/src/cairo-tag-attributes-private.h
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/src/cairo-tag-attributes-private.h	                        (rev 0)
+++ trunk/Build/source/libs/cairo/cairo-src/src/cairo-tag-attributes-private.h	2018-10-20 03:19:36 UTC (rev 48952)
@@ -0,0 +1,99 @@
+/* -*- Mode: c; c-basic-offset: 4; indent-tabs-mode: t; tab-width: 8; -*- */
+/* cairo - a vector graphics library with display and print output
+ *
+ * Copyright © 2016 Adrian Johnson
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it either under the terms of the GNU Lesser General Public
+ * License version 2.1 as published by the Free Software Foundation
+ * (the "LGPL") or, at your option, under the terms of the Mozilla
+ * Public License Version 1.1 (the "MPL"). If you do not alter this
+ * notice, a recipient may use your version of this file under either
+ * the MPL or the LGPL.
+ *
+ * You should have received a copy of the LGPL along with this library
+ * in the file COPYING-LGPL-2.1; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
+ * You should have received a copy of the MPL along with this library
+ * in the file COPYING-MPL-1.1
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
+ * OF ANY KIND, either express or implied. See the LGPL or the MPL for
+ * the specific language governing rights and limitations.
+ *
+ * The Original Code is the cairo graphics library.
+ *
+ * The Initial Developer of the Original Code is Adrian Johnson.
+ *
+ * Contributor(s):
+ *	Adrian Johnson <ajohnson at redneon.com>
+ */
+
+#ifndef CAIRO_TAG_ATTRIBUTES_PRIVATE_H
+#define CAIRO_TAG_ATTRIBUTES_PRIVATE_H
+
+#include "cairo-array-private.h"
+#include "cairo-error-private.h"
+#include "cairo-types-private.h"
+
+typedef enum {
+    TAG_LINK_INVALID = 0,
+    TAG_LINK_EMPTY,
+    TAG_LINK_DEST,
+    TAG_LINK_URI,
+    TAG_LINK_FILE,
+} cairo_tag_link_type_t;
+
+typedef struct _cairo_link_attrs {
+    cairo_tag_link_type_t link_type;
+    cairo_array_t rects;
+    char *dest;
+    char *uri;
+    char *file;
+    int page;
+    cairo_bool_t has_pos;
+    cairo_point_double_t pos;
+} cairo_link_attrs_t;
+
+typedef struct _cairo_dest_attrs {
+    char *name;
+    double x;
+    double y;
+    cairo_bool_t x_valid;
+    cairo_bool_t y_valid;
+    cairo_bool_t internal;
+} cairo_dest_attrs_t;
+
+typedef struct _cairo_ccitt_params {
+    int columns;
+    int rows;
+    int k;
+    cairo_bool_t end_of_line;
+    cairo_bool_t encoded_byte_align;
+    cairo_bool_t end_of_block;
+    cairo_bool_t black_is_1;
+    int damaged_rows_before_error;
+} cairo_ccitt_params_t;
+
+typedef struct _cairo_eps_params {
+    cairo_box_double_t bbox;
+} cairo_eps_params_t;
+
+cairo_private cairo_int_status_t
+_cairo_tag_parse_link_attributes (const char *attributes, cairo_link_attrs_t *link_attrs);
+
+cairo_private cairo_int_status_t
+_cairo_tag_parse_dest_attributes (const char *attributes, cairo_dest_attrs_t *dest_attrs);
+
+cairo_private cairo_int_status_t
+_cairo_tag_parse_ccitt_params (const char *attributes, cairo_ccitt_params_t *dest_attrs);
+
+cairo_private cairo_int_status_t
+_cairo_tag_parse_eps_params (const char *attributes, cairo_eps_params_t *dest_attrs);
+
+#endif /* CAIRO_TAG_ATTRIBUTES_PRIVATE_H */


Property changes on: trunk/Build/source/libs/cairo/cairo-src/src/cairo-tag-attributes-private.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+LF
\ No newline at end of property
Added: trunk/Build/source/libs/cairo/cairo-src/src/cairo-tag-attributes.c
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/src/cairo-tag-attributes.c	                        (rev 0)
+++ trunk/Build/source/libs/cairo/cairo-src/src/cairo-tag-attributes.c	2018-10-20 03:19:36 UTC (rev 48952)
@@ -0,0 +1,702 @@
+/* -*- Mode: c; c-basic-offset: 4; indent-tabs-mode: t; tab-width: 8; -*- */
+/* cairo - a vector graphics library with display and print output
+ *
+ * Copyright © 2016 Adrian Johnson
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it either under the terms of the GNU Lesser General Public
+ * License version 2.1 as published by the Free Software Foundation
+ * (the "LGPL") or, at your option, under the terms of the Mozilla
+ * Public License Version 1.1 (the "MPL"). If you do not alter this
+ * notice, a recipient may use your version of this file under either
+ * the MPL or the LGPL.
+ *
+ * You should have received a copy of the LGPL along with this library
+ * in the file COPYING-LGPL-2.1; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
+ * You should have received a copy of the MPL along with this library
+ * in the file COPYING-MPL-1.1
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
+ * OF ANY KIND, either express or implied. See the LGPL or the MPL for
+ * the specific language governing rights and limitations.
+ *
+ * The Original Code is the cairo graphics library.
+ *
+ * The Initial Developer of the Original Code is Adrian Johnson.
+ *
+ * Contributor(s):
+ *	Adrian Johnson <ajohnson at redneon.com>
+ */
+
+#include "cairoint.h"
+
+#include "cairo-array-private.h"
+#include "cairo-list-inline.h"
+#include "cairo-tag-attributes-private.h"
+
+#include <string.h>
+
+typedef enum {
+    ATTRIBUTE_BOOL,  /* Either true/false or 1/0 may be used. */
+    ATTRIBUTE_INT,
+    ATTRIBUTE_FLOAT, /* Decimal separator is in current locale. */
+    ATTRIBUTE_STRING, /* Enclose in single quotes. String escapes:
+                       *   \'  - single quote
+                       *   \\  - backslash
+                       */
+} attribute_type_t;
+
+typedef struct _attribute_spec {
+    const char *name;
+    attribute_type_t type;
+    int array_size; /* 0 = scalar, -1 = variable size array */
+} attribute_spec_t;
+
+/*
+ * name [required] Unique name of this destination (UTF-8)
+ * x    [optional] x coordinate of destination on page. Default is x coord of
+ *                 extents of operations enclosed by the dest begin/end tags.
+ * y    [optional] y coordinate of destination on page. Default is y coord of
+ *                 extents of operations enclosed by the dest begin/end tags.
+ * internal [optional] If true, the name may be optimized out of the PDF where
+ *                     possible. Default false.
+ */
+static attribute_spec_t _dest_attrib_spec[] = {
+    { "name",     ATTRIBUTE_STRING },
+    { "x",        ATTRIBUTE_FLOAT },
+    { "y",        ATTRIBUTE_FLOAT },
+    { "internal", ATTRIBUTE_BOOL },
+    { NULL }
+};
+
+/*
+ * rect [optional] One or more rectangles to define link region. Default
+ *                 is the extents of the operations enclosed by the link begin/end tags.
+ *                 Each rectangle is specified by four array elements: x, y, width, height.
+ *                 ie the array size must be a multiple of four.
+ *
+ * Internal Links
+ * --------------
+ * either:
+ *   dest - name of dest tag in the PDF file to link to (UTF8)
+ * or
+ *   page - Page number in the PDF file to link to
+ *   pos  - [optional] Position of destination on page. Default is 0,0.
+ *
+ * URI Links
+ * ---------
+ * uri [required] Uniform resource identifier (ASCII).
+
+ * File Links
+ * ----------
+ * file - [required] File name of PDF file to link to.
+ *   either:
+ *     dest - name of dest tag in the PDF file to link to (UTF8)
+ *   or
+ *     page - Page number in the PDF file to link to
+ *     pos  - [optional] Position of destination on page. Default is 0,0.
+ */
+static attribute_spec_t _link_attrib_spec[] =
+{
+    { "rect", ATTRIBUTE_FLOAT, -1 },
+    { "dest", ATTRIBUTE_STRING },
+    { "uri",  ATTRIBUTE_STRING },
+    { "file", ATTRIBUTE_STRING },
+    { "page", ATTRIBUTE_INT },
+    { "pos",  ATTRIBUTE_FLOAT, 2 },
+    { NULL }
+};
+
+/*
+ * Required:
+ *   Columns - width of the image in pixels.
+ *   Rows    - height of the image in scan lines.
+ *
+ * Optional:
+ *   K - An integer identifying the encoding scheme used. < 0 is 2 dimensional
+ *       Group 4, = 0 is Group3 1 dimensional, > 0 is mixed 1 and 2 dimensional
+ *       encoding. Default: 0.
+ *   EndOfLine  - If true end-of-line bit patterns are present. Default: false.
+ *   EncodedByteAlign - If true the end of line is padded with 0 bits so the next
+ *                      line begins on a byte boundary. Default: false.
+ *   EndOfBlock - If true the data contains an end-of-block pattern. Default: true.
+ *   BlackIs1   - If true 1 bits are black pixels. Default: false.
+ *   DamagedRowsBeforeError - Number of damages rows tolerated before an error
+ *                            occurs. Default: 0.
+ */
+static attribute_spec_t _ccitt_params_spec[] =
+{
+    { "Columns",                ATTRIBUTE_INT },
+    { "Rows",                   ATTRIBUTE_INT },
+    { "K",                      ATTRIBUTE_INT },
+    { "EndOfLine",              ATTRIBUTE_BOOL },
+    { "EncodedByteAlign",       ATTRIBUTE_BOOL },
+    { "EndOfBlock",             ATTRIBUTE_BOOL },
+    { "BlackIs1",               ATTRIBUTE_BOOL },
+    { "DamagedRowsBeforeError", ATTRIBUTE_INT },
+    { NULL }
+};
+
+/*
+ * bbox - Bounding box of EPS file. The format is [ llx lly urx ury ]
+ *          llx - lower left x xoordinate
+ *          lly - lower left y xoordinate
+ *          urx - upper right x xoordinate
+ *          ury - upper right y xoordinate
+ *        all cordinates are in PostScript coordinates.
+ */
+static attribute_spec_t _eps_params_spec[] =
+{
+    { "bbox", ATTRIBUTE_FLOAT, 4 },
+    { NULL }
+};
+
+typedef union {
+    cairo_bool_t b;
+    int i;
+    double f;
+    char *s;
+} attrib_val_t;
+
+typedef struct _attribute {
+    char *name;
+    attribute_type_t type;
+    int array_len; /* 0 = scalar */
+    attrib_val_t scalar;
+    cairo_array_t array; /* array of attrib_val_t */
+    cairo_list_t link;
+} attribute_t;
+
+static const char *
+skip_space (const char *p)
+{
+    while (_cairo_isspace (*p))
+	p++;
+
+    return p;
+}
+
+static const char *
+parse_bool (const char *p, cairo_bool_t *b)
+{
+    if (*p == '1') {
+	*b = TRUE;
+	return p + 1;
+    } else if (*p == '0') {
+	*b = FALSE;
+	return p + 1;
+    } else if (strcmp (p, "true") == 0) {
+	*b = TRUE;
+	return p + 4;
+    } else if (strcmp (p, "false") == 0) {
+	*b = FALSE;
+	return p + 5;
+    }
+
+    return NULL;
+}
+
+static const char *
+parse_int (const char *p, int *i)
+{
+    int n;
+
+    if (sscanf(p, "%d%n", i, &n) > 0)
+	return p + n;
+
+    return NULL;
+}
+
+static const char *
+parse_float (const char *p, double *d)
+{
+    int n;
+
+    if (sscanf(p, "%lf%n", d, &n) > 0)
+	return p + n;
+
+    return NULL;
+}
+
+static const char *
+decode_string (const char *p, int *len, char *s)
+{
+    if (*p != '\'')
+	return NULL;
+
+    p++;
+    if (! *p)
+	return NULL;
+
+    *len = 0;
+    while (*p) {
+	if (*p == '\\') {
+	    p++;
+	    if (*p) {
+		if (s)
+		    *s++ = *p;
+		p++;
+		(*len)++;
+	    }
+	} else if (*p == '\'') {
+	    return p + 1;
+	} else {
+	    if (s)
+		*s++ = *p;
+	    p++;
+	    (*len)++;
+	}
+    }
+
+    return NULL;
+}
+
+static const char *
+parse_string (const char *p, char **s)
+{
+    const char *end;
+    int len;
+
+    end = decode_string (p, &len, NULL);
+    if (!end)
+	return NULL;
+
+    *s = _cairo_malloc (len + 1);
+    decode_string (p, &len, *s);
+    (*s)[len] = 0;
+
+    return end;
+}
+
+static const char *
+parse_scalar (const char *p, attribute_type_t type, attrib_val_t *scalar)
+{
+    switch (type) {
+	case ATTRIBUTE_BOOL:
+	    return parse_bool (p, &scalar->b);
+	case ATTRIBUTE_INT:
+	    return parse_int (p, &scalar->i);
+	case ATTRIBUTE_FLOAT:
+	    return parse_float (p, &scalar->f);
+	case ATTRIBUTE_STRING:
+	    return parse_string (p, &scalar->s);
+    }
+
+    return NULL;
+}
+
+static cairo_int_status_t
+parse_array (const char *p, attribute_type_t type, cairo_array_t *array, const char **end)
+{
+    attrib_val_t val;
+    cairo_int_status_t status;
+
+    p = skip_space (p);
+    if (! *p)
+	return _cairo_error (CAIRO_INT_STATUS_TAG_ERROR);
+
+    if (*p++ != '[')
+	return _cairo_error (CAIRO_INT_STATUS_TAG_ERROR);
+
+    while (TRUE) {
+	p = skip_space (p);
+	if (! *p)
+	    return _cairo_error (CAIRO_INT_STATUS_TAG_ERROR);
+
+	if (*p == ']') {
+	    *end = p + 1;
+	    return CAIRO_INT_STATUS_SUCCESS;
+	}
+
+	p = parse_scalar (p, type, &val);
+	if (!p)
+	    return _cairo_error (CAIRO_INT_STATUS_TAG_ERROR);
+
+	status = _cairo_array_append (array, &val);
+	if (unlikely (status))
+	    return status;
+    }
+
+    return _cairo_error (CAIRO_INT_STATUS_TAG_ERROR);
+}
+
+static cairo_int_status_t
+parse_name (const char *p, const char **end, char **s)
+{
+    const char *p2;
+    char *name;
+    int len;
+
+    if (! _cairo_isalpha (*p))
+	return _cairo_error (CAIRO_INT_STATUS_TAG_ERROR);
+
+    p2 = p;
+    while (_cairo_isalpha (*p2) || _cairo_isdigit (*p2))
+	p2++;
+
+    len = p2 - p;
+    name = _cairo_malloc (len + 1);
+    if (unlikely (name == NULL))
+	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
+
+    memcpy (name, p, len);
+    name[len] = 0;
+    *s = name;
+    *end = p2;
+
+    return CAIRO_INT_STATUS_SUCCESS;
+}
+
+static cairo_int_status_t
+parse_attributes (const char *attributes, attribute_spec_t *attrib_def, cairo_list_t *list)
+{
+    attribute_spec_t *def;
+    attribute_t *attrib;
+    char *name = NULL;
+    cairo_int_status_t status;
+    const char *p = attributes;
+
+    if (! p)
+	return _cairo_error (CAIRO_INT_STATUS_TAG_ERROR);
+
+    while (*p) {
+	p = skip_space (p);
+	if (! *p)
+	    break;
+
+	status = parse_name (p, &p, &name);
+	if (status)
+	    return status;
+
+	def = attrib_def;
+	while (def->name) {
+	    if (strcmp (name, def->name) == 0)
+		break;
+	    def++;
+	}
+	if (! def->name) {
+	    status = _cairo_error (CAIRO_INT_STATUS_TAG_ERROR);
+	    goto fail1;
+	}
+
+	attrib = calloc (1, sizeof (attribute_t));
+	if (unlikely (attrib == NULL)) {
+	    status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
+	    goto fail1;
+	}
+
+	attrib->name = name;
+	attrib->type = def->type;
+	_cairo_array_init (&attrib->array, sizeof(attrib_val_t));
+
+	p = skip_space (p);
+	if (def->type == ATTRIBUTE_BOOL && *p != '=') {
+	    attrib->scalar.b = TRUE;
+	} else {
+	    if (*p++ != '=') {
+		status = _cairo_error (CAIRO_INT_STATUS_TAG_ERROR);
+		goto fail2;
+	    }
+
+	    if (def->array_size == 0) {
+		p = parse_scalar (p, def->type, &attrib->scalar);
+		if (!p) {
+		    status = _cairo_error (CAIRO_INT_STATUS_TAG_ERROR);
+		    goto fail2;
+		}
+
+		attrib->array_len = 0;
+	    } else {
+		status = parse_array (p, def->type, &attrib->array, &p);
+		if (unlikely (status))
+		    goto fail2;
+
+		attrib->array_len = _cairo_array_num_elements (&attrib->array);
+		if (def->array_size > 0 && attrib->array_len != def->array_size) {
+		    status = _cairo_error (CAIRO_INT_STATUS_TAG_ERROR);
+		    goto fail2;
+		}
+	    }
+	}
+
+	cairo_list_add_tail (&attrib->link, list);
+    }
+
+    return CAIRO_INT_STATUS_SUCCESS;
+
+  fail2:
+    _cairo_array_fini (&attrib->array);
+    if (attrib->type == ATTRIBUTE_STRING)
+	free (attrib->scalar.s);
+    free (attrib);
+  fail1:
+    free (name);
+
+    return status;
+}
+
+static void
+free_attributes_list (cairo_list_t *list)
+{
+    attribute_t *attr, *next;
+
+    cairo_list_foreach_entry_safe (attr, next, attribute_t, list, link)
+    {
+	cairo_list_del (&attr->link);
+	free (attr->name);
+	_cairo_array_fini (&attr->array);
+	if (attr->type == ATTRIBUTE_STRING)
+	    free (attr->scalar.s);
+	free (attr);
+    }
+}
+
+static attribute_t *
+find_attribute (cairo_list_t *list, const char *name)
+{
+    attribute_t *attr;
+
+    cairo_list_foreach_entry (attr, attribute_t, list, link)
+    {
+	if (strcmp (attr->name, name) == 0)
+	    return attr;
+    }
+
+    return NULL;
+}
+
+cairo_int_status_t
+_cairo_tag_parse_link_attributes (const char *attributes, cairo_link_attrs_t *link_attrs)
+{
+    cairo_list_t list;
+    cairo_int_status_t status;
+    attribute_t *attr;
+    attrib_val_t val;
+
+    cairo_list_init (&list);
+    status = parse_attributes (attributes, _link_attrib_spec, &list);
+    if (unlikely (status))
+	return status;
+
+    memset (link_attrs, 0, sizeof (cairo_link_attrs_t));
+    _cairo_array_init (&link_attrs->rects, sizeof (cairo_rectangle_t));
+    if (find_attribute (&list, "uri")) {
+	link_attrs->link_type = TAG_LINK_URI;
+    } else if (find_attribute (&list, "file")) {
+	link_attrs->link_type = TAG_LINK_FILE;
+    } else if (find_attribute (&list, "dest")) {
+	link_attrs->link_type = TAG_LINK_DEST;
+    } else if (find_attribute (&list, "page")) {
+	link_attrs->link_type = TAG_LINK_DEST;
+    } else {
+	link_attrs->link_type = TAG_LINK_EMPTY;
+	goto cleanup;
+    }
+
+    cairo_list_foreach_entry (attr, attribute_t, &list, link)
+    {
+	if (strcmp (attr->name, "uri") == 0) {
+	    if (link_attrs->link_type != TAG_LINK_URI) {
+		status = _cairo_error (CAIRO_INT_STATUS_TAG_ERROR);
+		goto cleanup;
+	    }
+
+	    link_attrs->uri = strdup (attr->scalar.s);
+	} else if (strcmp (attr->name, "file") == 0) {
+	    if (link_attrs->link_type != TAG_LINK_FILE) {
+		status = _cairo_error (CAIRO_INT_STATUS_TAG_ERROR);
+		goto cleanup;
+	    }
+
+	    link_attrs->file = strdup (attr->scalar.s);
+	} else if (strcmp (attr->name, "dest") == 0) {
+	    if (! (link_attrs->link_type == TAG_LINK_DEST ||
+		   link_attrs->link_type != TAG_LINK_FILE)) {
+		status = _cairo_error (CAIRO_INT_STATUS_TAG_ERROR);
+		goto cleanup;
+	    }
+
+	    link_attrs->dest = strdup (attr->scalar.s);
+	} else if (strcmp (attr->name, "page") == 0) {
+	    if (! (link_attrs->link_type == TAG_LINK_DEST ||
+		   link_attrs->link_type != TAG_LINK_FILE)) {
+		status = _cairo_error (CAIRO_INT_STATUS_TAG_ERROR);
+		goto cleanup;
+	    }
+
+	    link_attrs->page = attr->scalar.i;
+
+	} else if (strcmp (attr->name, "pos") == 0) {
+	    if (! (link_attrs->link_type == TAG_LINK_DEST ||
+		   link_attrs->link_type != TAG_LINK_FILE)) {
+		status = _cairo_error (CAIRO_INT_STATUS_TAG_ERROR);
+		goto cleanup;
+	    }
+
+	    _cairo_array_copy_element (&attr->array, 0, &val);
+	    link_attrs->pos.x = val.f;
+	    _cairo_array_copy_element (&attr->array, 1, &val);
+	    link_attrs->pos.y = val.f;
+	    link_attrs->has_pos = TRUE;
+	} else if (strcmp (attr->name, "rect") == 0) {
+	    cairo_rectangle_t rect;
+	    int i;
+	    int num_elem = _cairo_array_num_elements (&attr->array);
+	    if (num_elem == 0 || num_elem % 4 != 0) {
+		status = _cairo_error (CAIRO_INT_STATUS_TAG_ERROR);
+		goto cleanup;
+	    }
+
+	    for (i = 0; i < num_elem; i += 4) {
+		_cairo_array_copy_element (&attr->array, i, &val);
+		rect.x = val.f;
+		_cairo_array_copy_element (&attr->array, i+1, &val);
+		rect.y = val.f;
+		_cairo_array_copy_element (&attr->array, i+2, &val);
+		rect.width = val.f;
+		_cairo_array_copy_element (&attr->array, i+3, &val);
+		rect.height = val.f;
+		status = _cairo_array_append (&link_attrs->rects, &rect);
+		if (unlikely (status))
+		    goto cleanup;
+	    }
+	}
+    }
+
+  cleanup:
+    free_attributes_list (&list);
+    if (unlikely (status)) {
+	free (link_attrs->dest);
+	free (link_attrs->uri);
+	free (link_attrs->file);
+	_cairo_array_fini (&link_attrs->rects);
+    }
+
+    return status;
+}
+
+cairo_int_status_t
+_cairo_tag_parse_dest_attributes (const char *attributes, cairo_dest_attrs_t *dest_attrs)
+{
+    cairo_list_t list;
+    cairo_int_status_t status;
+    attribute_t *attr;
+
+    memset (dest_attrs, 0, sizeof (cairo_dest_attrs_t));
+    cairo_list_init (&list);
+    status = parse_attributes (attributes, _dest_attrib_spec, &list);
+    if (unlikely (status))
+	goto cleanup;
+
+    cairo_list_foreach_entry (attr, attribute_t, &list, link)
+    {
+	if (strcmp (attr->name, "name") == 0) {
+	    dest_attrs->name = strdup (attr->scalar.s);
+	} else if (strcmp (attr->name, "x") == 0) {
+	    dest_attrs->x = attr->scalar.f;
+	    dest_attrs->x_valid = TRUE;
+	} else if (strcmp (attr->name, "y") == 0) {
+	    dest_attrs->y = attr->scalar.f;
+	    dest_attrs->y_valid = TRUE;
+	} else if (strcmp (attr->name, "internal") == 0) {
+	    dest_attrs->internal = attr->scalar.b;
+	}
+    }
+
+    if (! dest_attrs->name)
+	status = _cairo_error (CAIRO_INT_STATUS_TAG_ERROR);
+
+  cleanup:
+    free_attributes_list (&list);
+
+    return status;
+}
+
+cairo_int_status_t
+_cairo_tag_parse_ccitt_params (const char *attributes, cairo_ccitt_params_t *ccitt_params)
+{
+    cairo_list_t list;
+    cairo_int_status_t status;
+    attribute_t *attr;
+
+    ccitt_params->columns = -1;
+    ccitt_params->rows = -1;
+
+    /* set defaults */
+    ccitt_params->k = 0;
+    ccitt_params->end_of_line = FALSE;
+    ccitt_params->encoded_byte_align = FALSE;
+    ccitt_params->end_of_block = TRUE;
+    ccitt_params->black_is_1 = FALSE;
+    ccitt_params->damaged_rows_before_error = 0;
+
+    cairo_list_init (&list);
+    status = parse_attributes (attributes, _ccitt_params_spec, &list);
+    if (unlikely (status))
+	goto cleanup;
+
+    cairo_list_foreach_entry (attr, attribute_t, &list, link)
+    {
+	if (strcmp (attr->name, "Columns") == 0) {
+	    ccitt_params->columns = attr->scalar.i;
+	} else if (strcmp (attr->name, "Rows") == 0) {
+	    ccitt_params->rows = attr->scalar.i;
+	} else if (strcmp (attr->name, "K") == 0) {
+	    ccitt_params->k = attr->scalar.i;
+	} else if (strcmp (attr->name, "EndOfLine") == 0) {
+	    ccitt_params->end_of_line = attr->scalar.b;
+	} else if (strcmp (attr->name, "EncodedByteAlign") == 0) {
+	    ccitt_params->encoded_byte_align = attr->scalar.b;
+	} else if (strcmp (attr->name, "EndOfBlock") == 0) {
+	    ccitt_params->end_of_block = attr->scalar.b;
+	} else if (strcmp (attr->name, "BlackIs1") == 0) {
+	    ccitt_params->black_is_1 = attr->scalar.b;
+	} else if (strcmp (attr->name, "DamagedRowsBeforeError") == 0) {
+	    ccitt_params->damaged_rows_before_error = attr->scalar.b;
+	}
+    }
+
+  cleanup:
+    free_attributes_list (&list);
+
+    return status;
+}
+
+cairo_int_status_t
+_cairo_tag_parse_eps_params (const char *attributes, cairo_eps_params_t *eps_params)
+{
+    cairo_list_t list;
+    cairo_int_status_t status;
+    attribute_t *attr;
+    attrib_val_t val;
+
+    cairo_list_init (&list);
+    status = parse_attributes (attributes, _eps_params_spec, &list);
+    if (unlikely (status))
+	goto cleanup;
+
+    cairo_list_foreach_entry (attr, attribute_t, &list, link)
+    {
+	if (strcmp (attr->name, "bbox") == 0) {
+	    _cairo_array_copy_element (&attr->array, 0, &val);
+	    eps_params->bbox.p1.x = val.f;
+	    _cairo_array_copy_element (&attr->array, 1, &val);
+	    eps_params->bbox.p1.y = val.f;
+	    _cairo_array_copy_element (&attr->array, 2, &val);
+	    eps_params->bbox.p2.x = val.f;
+	    _cairo_array_copy_element (&attr->array, 3, &val);
+	    eps_params->bbox.p2.y = val.f;
+	}
+    }
+
+  cleanup:
+    free_attributes_list (&list);
+
+    return status;
+}


Property changes on: trunk/Build/source/libs/cairo/cairo-src/src/cairo-tag-attributes.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+LF
\ No newline at end of property
Added: trunk/Build/source/libs/cairo/cairo-src/src/cairo-tag-stack-private.h
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/src/cairo-tag-stack-private.h	                        (rev 0)
+++ trunk/Build/source/libs/cairo/cairo-src/src/cairo-tag-stack-private.h	2018-10-20 03:19:36 UTC (rev 48952)
@@ -0,0 +1,107 @@
+/* -*- Mode: c; c-basic-offset: 4; indent-tabs-mode: t; tab-width: 8; -*- */
+/* cairo - a vector graphics library with display and print output
+ *
+ * Copyright © 2016 Adrian Johnson
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it either under the terms of the GNU Lesser General Public
+ * License version 2.1 as published by the Free Software Foundation
+ * (the "LGPL") or, at your option, under the terms of the Mozilla
+ * Public License Version 1.1 (the "MPL"). If you do not alter this
+ * notice, a recipient may use your version of this file under either
+ * the MPL or the LGPL.
+ *
+ * You should have received a copy of the LGPL along with this library
+ * in the file COPYING-LGPL-2.1; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
+ * You should have received a copy of the MPL along with this library
+ * in the file COPYING-MPL-1.1
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
+ * OF ANY KIND, either express or implied. See the LGPL or the MPL for
+ * the specific language governing rights and limitations.
+ *
+ * The Original Code is the cairo graphics library.
+ *
+ * The Initial Developer of the Original Code is Adrian Johnson.
+ *
+ * Contributor(s):
+ *	Adrian Johnson <ajohnson at redneon.com>
+ */
+
+#ifndef CAIRO_TAG_STACK_PRIVATE_H
+#define CAIRO_TAG_STACK_PRIVATE_H
+
+#include "cairo-error-private.h"
+#include "cairo-list-inline.h"
+
+/* The type of a single tag */
+typedef enum {
+    TAG_TYPE_INVALID = 0,
+    TAG_TYPE_STRUCTURE = 1,
+    TAG_TYPE_LINK = 2,
+    TAG_TYPE_DEST = 4,
+} cairo_tag_type_t;
+
+/* The type of the structure tree. */
+typedef enum _cairo_tag_stack_structure_type {
+    TAG_TREE_TYPE_TAGGED, /* compliant with Tagged PDF */
+    TAG_TREE_TYPE_STRUCTURE, /* valid structure but not 'Tagged PDF' compliant */
+    TAG_TREE_TYPE_LINK_ONLY, /* contains Link tags only */
+    TAG_TREE_TYPE_NO_TAGS, /* no tags used */
+    TAG_TREE_TYPE_INVALID, /* invalid tag structure */
+} cairo_tag_stack_structure_type_t;
+
+typedef struct _cairo_tag_stack_elem {
+    char *name;
+    char *attributes;
+    void *data;
+    cairo_list_t link;
+
+} cairo_tag_stack_elem_t;
+
+typedef struct _cairo_tag_stack {
+    cairo_list_t list;
+    cairo_tag_stack_structure_type_t type;
+    int size;
+
+} cairo_tag_stack_t;
+
+cairo_private void
+_cairo_tag_stack_init (cairo_tag_stack_t *stack);
+
+cairo_private void
+_cairo_tag_stack_fini (cairo_tag_stack_t *stack);
+
+cairo_private cairo_tag_stack_structure_type_t
+_cairo_tag_stack_get_structure_type (cairo_tag_stack_t *stack);
+
+cairo_private cairo_int_status_t
+_cairo_tag_stack_push (cairo_tag_stack_t *stack,
+		       const char        *name,
+		       const char        *attributes);
+
+cairo_private void
+_cairo_tag_stack_set_top_data (cairo_tag_stack_t *stack,
+			       void              *data);
+
+cairo_private cairo_int_status_t
+_cairo_tag_stack_pop (cairo_tag_stack_t *stack,
+		      const char *name,
+		      cairo_tag_stack_elem_t **elem);
+
+cairo_private cairo_tag_stack_elem_t *
+_cairo_tag_stack_top_elem (cairo_tag_stack_t *stack);
+
+cairo_private void
+_cairo_tag_stack_free_elem (cairo_tag_stack_elem_t *elem);
+
+cairo_private cairo_tag_type_t
+_cairo_tag_get_type (const char *name);
+
+#endif /* CAIRO_TAG_STACK_PRIVATE_H */


Property changes on: trunk/Build/source/libs/cairo/cairo-src/src/cairo-tag-stack-private.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+LF
\ No newline at end of property
Added: trunk/Build/source/libs/cairo/cairo-src/src/cairo-tag-stack.c
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/src/cairo-tag-stack.c	                        (rev 0)
+++ trunk/Build/source/libs/cairo/cairo-src/src/cairo-tag-stack.c	2018-10-20 03:19:36 UTC (rev 48952)
@@ -0,0 +1,280 @@
+/* -*- Mode: c; c-basic-offset: 4; indent-tabs-mode: t; tab-width: 8; -*- */
+/* cairo - a vector graphics library with display and print output
+ *
+ * Copyright © 2016 Adrian Johnson
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it either under the terms of the GNU Lesser General Public
+ * License version 2.1 as published by the Free Software Foundation
+ * (the "LGPL") or, at your option, under the terms of the Mozilla
+ * Public License Version 1.1 (the "MPL"). If you do not alter this
+ * notice, a recipient may use your version of this file under either
+ * the MPL or the LGPL.
+ *
+ * You should have received a copy of the LGPL along with this library
+ * in the file COPYING-LGPL-2.1; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
+ * You should have received a copy of the MPL along with this library
+ * in the file COPYING-MPL-1.1
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
+ * OF ANY KIND, either express or implied. See the LGPL or the MPL for
+ * the specific language governing rights and limitations.
+ *
+ * The Original Code is the cairo graphics library.
+ *
+ * The Initial Developer of the Original Code is Adrian Johnson.
+ *
+ * Contributor(s):
+ *	Adrian Johnson <ajohnson at redneon.com>
+ */
+
+#include "cairoint.h"
+
+#include "cairo-tag-stack-private.h"
+
+/* Tagged PDF must have one of these tags at the top level */
+static const char * _cairo_tag_stack_tagged_pdf_top_level_element_list[] =
+{
+    "Document",
+    "Part",
+    "Art",
+    "Sect",
+    "Div",
+    NULL
+};
+
+/* List of valid tag names. Table numbers reference PDF 32000 */
+static const char * _cairo_tag_stack_struct_pdf_list[] =
+{
+    /* Table 333 - Grouping Elements */
+    "Document",
+    "Part",
+    "Art",
+    "Sect",
+    "Div",
+    "BlockQuote",
+    "Caption",
+    "TOC",
+    "TOCI",
+    "Index",
+    "NonStruct",
+    "Private",
+
+    /* Table 335 - Standard structure types for paragraphlike elements */
+    "P", "H",
+    "H1", "H2", "H3", "H4", "H5", "H6",
+
+    /* Table 336 - Standard structure types for list elements */
+    "L", "LI", "Lbl", "LBody",
+
+    /* Table 337 - Standard structure types for table elements */
+    "Table",
+    "TR", "TH", "TD",
+    "THead", "TBody", "TFoot",
+
+    /* Table 338 - Standard structure types for inline-level structure elements */
+    "Span",
+    "Quote",
+    "Note",
+    "Reference",
+    "BibEntry",
+    "Code",
+    "Link", /* CAIRO_TAG_LINK */
+    "Annot",
+    "Ruby",
+    "Warichu",
+
+    /* Table 339 - Standard structure types for Ruby and Warichu elements */
+    "RB", "RT", "RP",
+    "WT", "WP",
+
+    /* Table 340 - Standard structure types for illustration elements */
+    "Figure",
+    "Formula",
+    "Form",
+
+    NULL
+};
+
+/* List of cairo specific tag names */
+static const char * _cairo_tag_stack_cairo_tag_list[] =
+{
+    CAIRO_TAG_DEST,
+    NULL
+};
+
+void
+_cairo_tag_stack_init (cairo_tag_stack_t *stack)
+{
+    cairo_list_init (&stack->list);
+    stack->type = TAG_TREE_TYPE_NO_TAGS;
+    stack->size = 0;
+}
+
+void
+_cairo_tag_stack_fini (cairo_tag_stack_t *stack)
+{
+    while (! cairo_list_is_empty (&stack->list)) {
+	cairo_tag_stack_elem_t *elem;
+
+	elem = cairo_list_first_entry (&stack->list, cairo_tag_stack_elem_t, link);
+	cairo_list_del (&elem->link);
+	free (elem->name);
+	free (elem->attributes);
+	free (elem);
+    }
+}
+
+cairo_tag_stack_structure_type_t
+_cairo_tag_stack_get_structure_type (cairo_tag_stack_t *stack)
+{
+    return stack->type;
+}
+
+static cairo_bool_t
+name_in_list (const char *name, const char **list)
+{
+    if (! name)
+	return FALSE;
+
+    while (*list) {
+	if (strcmp (name, *list) == 0)
+	    return TRUE;
+	list++;
+    }
+
+    return FALSE;
+}
+
+cairo_int_status_t
+_cairo_tag_stack_push (cairo_tag_stack_t *stack,
+		       const char        *name,
+		       const char        *attributes)
+{
+    cairo_tag_stack_elem_t *elem;
+
+    if (! name_in_list (name, _cairo_tag_stack_struct_pdf_list) &&
+	! name_in_list (name, _cairo_tag_stack_cairo_tag_list))
+    {
+	stack->type = TAG_TYPE_INVALID;
+	return _cairo_error (CAIRO_STATUS_TAG_ERROR);
+    }
+
+    if (stack->type == TAG_TREE_TYPE_NO_TAGS) {
+	if (name_in_list (name, _cairo_tag_stack_tagged_pdf_top_level_element_list))
+	    stack->type = TAG_TREE_TYPE_TAGGED;
+	else if (strcmp (name, "Link") == 0)
+	    stack->type = TAG_TREE_TYPE_LINK_ONLY;
+	else if (name_in_list (name, _cairo_tag_stack_struct_pdf_list))
+	    stack->type = TAG_TREE_TYPE_STRUCTURE;
+    } else {
+	if (stack->type == TAG_TREE_TYPE_LINK_ONLY &&
+	    (strcmp (name, "Link") != 0) &&
+	    name_in_list (name, _cairo_tag_stack_struct_pdf_list))
+	{
+	    stack->type = TAG_TREE_TYPE_STRUCTURE;
+	}
+    }
+
+    elem = _cairo_malloc (sizeof(cairo_tag_stack_elem_t));
+    if (unlikely (elem == NULL))
+	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
+
+    elem->name = strdup (name);
+    if (unlikely (elem->name == NULL))
+	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
+
+    if (attributes) {
+	elem->attributes = strdup (attributes);
+	if (unlikely (elem->attributes == NULL))
+	    return _cairo_error (CAIRO_STATUS_NO_MEMORY);
+    } else {
+	elem->attributes = NULL;
+    }
+
+    elem->data = NULL;
+
+    cairo_list_add_tail (&elem->link, &stack->list);
+    stack->size++;
+
+    return CAIRO_STATUS_SUCCESS;
+}
+
+cairo_private void
+_cairo_tag_stack_set_top_data (cairo_tag_stack_t *stack,
+			       void        *data)
+{
+    cairo_tag_stack_elem_t *top;
+
+    top = _cairo_tag_stack_top_elem (stack);
+    if (top)
+	top->data = data;
+}
+
+cairo_int_status_t
+_cairo_tag_stack_pop (cairo_tag_stack_t *stack,
+		      const char *name,
+		      cairo_tag_stack_elem_t **elem)
+{
+    cairo_tag_stack_elem_t *top;
+
+    top = _cairo_tag_stack_top_elem (stack);
+    if (!top) {
+	stack->type = TAG_TYPE_INVALID;
+	return _cairo_error (CAIRO_STATUS_TAG_ERROR);
+    }
+
+    cairo_list_del (&top->link);
+    stack->size--;
+    if (strcmp (top->name, name) != 0) {
+	stack->type = TAG_TYPE_INVALID;
+	_cairo_tag_stack_free_elem (top);
+	return _cairo_error (CAIRO_STATUS_TAG_ERROR);
+    }
+
+    if (elem)
+	*elem = top;
+    else
+	_cairo_tag_stack_free_elem (top);
+
+    return CAIRO_STATUS_SUCCESS;
+}
+
+cairo_tag_stack_elem_t *
+_cairo_tag_stack_top_elem (cairo_tag_stack_t *stack)
+{
+    if (cairo_list_is_empty (&stack->list))
+	return NULL;
+
+    return cairo_list_last_entry (&stack->list, cairo_tag_stack_elem_t, link);
+}
+
+void
+_cairo_tag_stack_free_elem (cairo_tag_stack_elem_t *elem)
+{
+    free (elem->name);
+    free (elem->attributes);
+    free (elem);
+}
+
+cairo_tag_type_t
+_cairo_tag_get_type (const char *name)
+{
+    if (! name_in_list (name, _cairo_tag_stack_struct_pdf_list) &&
+	! name_in_list (name, _cairo_tag_stack_cairo_tag_list))
+	return TAG_TYPE_INVALID;
+
+    if (strcmp(name, "Link") == 0)
+	return (TAG_TYPE_LINK | TAG_TYPE_STRUCTURE);
+
+    if (strcmp(name, "cairo.dest") == 0)
+	return TAG_TYPE_DEST;
+
+    return TAG_TYPE_STRUCTURE;
+}


Property changes on: trunk/Build/source/libs/cairo/cairo-src/src/cairo-tag-stack.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+LF
\ No newline at end of property
Modified: trunk/Build/source/libs/cairo/cairo-src/src/cairo-tee-surface.c
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/src/cairo-tee-surface.c	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/src/cairo-tee-surface.c	2018-10-20 03:19:36 UTC (rev 48952)
@@ -428,7 +428,7 @@
     if (unlikely (master->status))
 	return _cairo_surface_create_in_error (master->status);
 
-    surface = malloc (sizeof (cairo_tee_surface_t));
+    surface = _cairo_malloc (sizeof (cairo_tee_surface_t));
     if (unlikely (surface == NULL))
 	return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
 
@@ -435,7 +435,8 @@
     _cairo_surface_init (&surface->base,
 			 &cairo_tee_surface_backend,
 			 master->device,
-			 master->content);
+			 master->content,
+			 TRUE); /* is_vector */
 
     _cairo_surface_wrapper_init (&surface->master, master);
 

Modified: trunk/Build/source/libs/cairo/cairo-src/src/cairo-tor-scan-converter.c
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/src/cairo-tor-scan-converter.c	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/src/cairo-tor-scan-converter.c	2018-10-20 03:19:36 UTC (rev 48952)
@@ -29,7 +29,7 @@
  * The source is from commit 734c53237a867a773640bd5b64816249fa1730f8
  * of
  *
- *   http://gitweb.freedesktop.org/?p=users/joonas/glitter-paths
+ *   https://gitweb.freedesktop.org/?p=users/joonas/glitter-paths
  */
 /* Glitter-paths is a stand alone polygon rasteriser derived from
  * David Turner's reimplementation of Tor Anderssons's 15x17
@@ -483,7 +483,7 @@
 {
     struct _pool_chunk *p;
 
-    p = malloc(SIZEOF_POOL_CHUNK + size);
+    p = _cairo_malloc (SIZEOF_POOL_CHUNK + size);
     if (unlikely (NULL == p))
 	longjmp (*pool->jmp, _cairo_error (CAIRO_STATUS_NO_MEMORY));
 
@@ -1872,7 +1872,7 @@
     cairo_tor_scan_converter_t *self;
     cairo_status_t status;
 
-    self = malloc (sizeof(struct _cairo_tor_scan_converter));
+    self = _cairo_malloc (sizeof(struct _cairo_tor_scan_converter));
     if (unlikely (self == NULL)) {
 	status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
 	goto bail_nomem;

Modified: trunk/Build/source/libs/cairo/cairo-src/src/cairo-tor22-scan-converter.c
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/src/cairo-tor22-scan-converter.c	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/src/cairo-tor22-scan-converter.c	2018-10-20 03:19:36 UTC (rev 48952)
@@ -29,7 +29,7 @@
  * The source is from commit 734c53237a867a773640bd5b64816249fa1730f8
  * of
  *
- *   http://gitweb.freedesktop.org/?p=users/joonas/glitter-paths
+ *   https://gitweb.freedesktop.org/?p=users/joonas/glitter-paths
  */
 /* Glitter-paths is a stand alone polygon rasteriser derived from
  * David Turner's reimplementation of Tor Anderssons's 15x17
@@ -504,7 +504,7 @@
 {
     struct _pool_chunk *p;
 
-    p = malloc(size + sizeof(struct _pool_chunk));
+    p = _cairo_malloc (size + sizeof(struct _pool_chunk));
     if (unlikely (NULL == p))
 	longjmp (*pool->jmp, _cairo_error (CAIRO_STATUS_NO_MEMORY));
 
@@ -1682,7 +1682,7 @@
     cairo_tor22_scan_converter_t *self;
     cairo_status_t status;
 
-    self = malloc (sizeof(struct _cairo_tor22_scan_converter));
+    self = _cairo_malloc (sizeof(struct _cairo_tor22_scan_converter));
     if (unlikely (self == NULL)) {
 	status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
 	goto bail_nomem;

Modified: trunk/Build/source/libs/cairo/cairo-src/src/cairo-toy-font-face.c
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/src/cairo-toy-font-face.c	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/src/cairo-toy-font-face.c	2018-10-20 03:19:36 UTC (rev 48952)
@@ -312,7 +312,7 @@
     }
 
     /* Otherwise create it and insert into hash table. */
-    font_face = malloc (sizeof (cairo_toy_font_face_t));
+    font_face = _cairo_malloc (sizeof (cairo_toy_font_face_t));
     if (unlikely (font_face == NULL)) {
 	status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
 	goto UNWIND_HASH_TABLE_LOCK;

Modified: trunk/Build/source/libs/cairo/cairo-src/src/cairo-traps.c
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/src/cairo-traps.c	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/src/cairo-traps.c	2018-10-20 03:19:36 UTC (rev 48952)
@@ -113,7 +113,7 @@
     if (traps->traps != traps->traps_embedded)
 	free (traps->traps);
 
-    VG (VALGRIND_MAKE_MEM_NOACCESS (traps, sizeof (cairo_traps_t)));
+    VG (VALGRIND_MAKE_MEM_UNDEFINED (traps, sizeof (cairo_traps_t)));
 }
 
 /* make room for at least one more trap */

Modified: trunk/Build/source/libs/cairo/cairo-src/src/cairo-tristrip.c
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/src/cairo-tristrip.c	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/src/cairo-tristrip.c	2018-10-20 03:19:36 UTC (rev 48952)
@@ -58,7 +58,7 @@
     if (strip->points != strip->points_embedded)
 	free (strip->points);
 
-    VG (VALGRIND_MAKE_MEM_NOACCESS (strip, sizeof (cairo_tristrip_t)));
+    VG (VALGRIND_MAKE_MEM_UNDEFINED (strip, sizeof (cairo_tristrip_t)));
 }
 
 

Modified: trunk/Build/source/libs/cairo/cairo-src/src/cairo-truetype-subset.c
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/src/cairo-truetype-subset.c	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/src/cairo-truetype-subset.c	2018-10-20 03:19:36 UTC (rev 48952)
@@ -77,22 +77,22 @@
     struct {
 	char *font_name;
 	char *ps_name;
-	unsigned int num_glyphs;
-	int *widths;
+	int num_glyphs_in_face; /* glyphs in font */
 	long x_min, y_min, x_max, y_max;
 	long ascent, descent;
         int  units_per_em;
     } base;
 
-    subset_glyph_t *glyphs;
+    subset_glyph_t *glyphs; /* array size: num_glyphs_in_face + 2 */
     const cairo_scaled_font_backend_t *backend;
-    int num_glyphs_in_face;
+    unsigned int num_glyphs; /* glyphs used */
+    int *widths; /* array size: num_glyphs_in_face  + 1 */
     int checksum_index;
     cairo_array_t output;
     cairo_array_t string_offsets;
     unsigned long last_offset;
     unsigned long last_boundary;
-    int *parent_to_subset;
+    int *parent_to_subset; /* array size: num_glyphs_in_face + 1 */
     cairo_status_t status;
     cairo_bool_t is_pdf;
 };
@@ -107,7 +107,6 @@
 check (tt_maxp_t,	32);
 check (tt_name_record_t, 12);
 check (tt_name_t,	18);
-check (tt_name_t,	18);
 check (tt_composite_glyph_t, 16);
 check (tt_glyph_data_t,	26);
 #undef check
@@ -139,6 +138,7 @@
 			     cairo_truetype_font_t      **font_return)
 {
     cairo_status_t status;
+    cairo_bool_t is_synthetic;
     cairo_truetype_font_t *font;
     const cairo_scaled_font_backend_t *backend;
     tt_head_t head;
@@ -159,10 +159,16 @@
      *   return CAIRO_INT_STATUS_UNSUPPORTED;
      */
 
-    /* We need to use a fallback font generated from the synthesized outlines. */
-    if (backend->is_synthetic && backend->is_synthetic (scaled_font_subset->scaled_font))
-       return CAIRO_INT_STATUS_UNSUPPORTED;
+    /* We need to use a fallback font if this font differs from the glyf outlines. */
+    if (backend->is_synthetic) {
+	status = backend->is_synthetic (scaled_font_subset->scaled_font, &is_synthetic);
+	if (unlikely (status))
+	    return status;
 
+	if (is_synthetic)
+	    return CAIRO_INT_STATUS_UNSUPPORTED;
+    }
+
     size = sizeof (tt_head_t);
     status = backend->load_truetype_table (scaled_font_subset->scaled_font,
                                           TT_TAG_head, 0,
@@ -187,12 +193,12 @@
     if (unlikely (status))
 	return status;
 
-    font = malloc (sizeof (cairo_truetype_font_t));
+    font = _cairo_malloc (sizeof (cairo_truetype_font_t));
     if (unlikely (font == NULL))
 	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
     font->backend = backend;
-    font->num_glyphs_in_face = be16_to_cpu (maxp.num_glyphs);
+    font->base.num_glyphs_in_face = be16_to_cpu (maxp.num_glyphs);
     font->scaled_font_subset = scaled_font_subset;
 
     font->last_offset = 0;
@@ -205,7 +211,7 @@
     /* Add 2: +1 case font does not contain .notdef, and +1 because an extra
      * entry is required to contain the end location of the last glyph.
      */
-    font->glyphs = calloc (font->num_glyphs_in_face + 2, sizeof (subset_glyph_t));
+    font->glyphs = calloc (font->base.num_glyphs_in_face + 2, sizeof (subset_glyph_t));
     if (unlikely (font->glyphs == NULL)) {
 	status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
 	goto fail1;
@@ -212,7 +218,7 @@
     }
 
     /* Add 1 in case font does not contain .notdef */
-    font->parent_to_subset = calloc (font->num_glyphs_in_face + 1, sizeof (int));
+    font->parent_to_subset = calloc (font->base.num_glyphs_in_face + 1, sizeof (int));
     if (unlikely (font->parent_to_subset == NULL)) {
 	status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
 	goto fail2;
@@ -219,7 +225,7 @@
     }
 
     font->is_pdf = is_pdf;
-    font->base.num_glyphs = 0;
+    font->num_glyphs = 0;
     font->base.x_min = (int16_t) be16_to_cpu (head.x_min);
     font->base.y_min = (int16_t) be16_to_cpu (head.y_min);
     font->base.x_max = (int16_t) be16_to_cpu (head.x_max);
@@ -240,7 +246,7 @@
 
     /* If the PS name is not found, create a CairoFont-x-y name. */
     if (font->base.ps_name == NULL) {
-        font->base.ps_name = malloc (30);
+        font->base.ps_name = _cairo_malloc (30);
         if (unlikely (font->base.ps_name == NULL)) {
 	    status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
             goto fail3;
@@ -252,8 +258,8 @@
     }
 
     /* Add 1 in case font does not contain .notdef */
-    font->base.widths = calloc (font->num_glyphs_in_face + 1, sizeof (int));
-    if (unlikely (font->base.widths == NULL)) {
+    font->widths = calloc (font->base.num_glyphs_in_face + 1, sizeof (int));
+    if (unlikely (font->widths == NULL)) {
 	status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
 	goto fail4;
     }
@@ -271,7 +277,7 @@
 
  fail5:
     _cairo_array_fini (&font->string_offsets);
-    free (font->base.widths);
+    free (font->widths);
  fail4:
     free (font->base.ps_name);
  fail3:
@@ -290,7 +296,7 @@
 cairo_truetype_font_destroy (cairo_truetype_font_t *font)
 {
     _cairo_array_fini (&font->string_offsets);
-    free (font->base.widths);
+    free (font->widths);
     free (font->base.ps_name);
     free (font->base.font_name);
     free (font->parent_to_subset);
@@ -612,11 +618,11 @@
 	return _cairo_truetype_font_set_error (font, status);
 
     if (be16_to_cpu (header.index_to_loc_format) == 0)
-	size = sizeof (int16_t) * (font->num_glyphs_in_face + 1);
+	size = sizeof (int16_t) * (font->base.num_glyphs_in_face + 1);
     else
-	size = sizeof (int32_t) * (font->num_glyphs_in_face + 1);
+	size = sizeof (int32_t) * (font->base.num_glyphs_in_face + 1);
 
-    u.bytes = malloc (size);
+    u.bytes = _cairo_malloc (size);
     if (unlikely (u.bytes == NULL))
 	return _cairo_truetype_font_set_error (font, CAIRO_STATUS_NO_MEMORY);
 
@@ -626,7 +632,7 @@
 	return _cairo_truetype_font_set_error (font, status);
 
     start_offset = _cairo_array_num_elements (&font->output);
-    for (i = 0; i < font->base.num_glyphs; i++) {
+    for (i = 0; i < font->num_glyphs; i++) {
 	index = font->glyphs[i].parent_index;
 	if (be16_to_cpu (header.index_to_loc_format) == 0) {
 	    begin = be16_to_cpu (u.short_offsets[index]) * 2;
@@ -754,7 +760,7 @@
     if (unlikely (status))
 	return _cairo_truetype_font_set_error (font, status);
 
-    hhea->num_hmetrics = cpu_to_be16 ((uint16_t)(font->base.num_glyphs));
+    hhea->num_hmetrics = cpu_to_be16 ((uint16_t)(font->num_glyphs));
 
     return CAIRO_STATUS_SUCCESS;
 }
@@ -784,7 +790,7 @@
 
     num_hmetrics = be16_to_cpu(hhea.num_hmetrics);
 
-    for (i = 0; i < font->base.num_glyphs; i++) {
+    for (i = 0; i < font->num_glyphs; i++) {
         long_entry_size = 2 * sizeof (int16_t);
         short_entry_size = sizeof (int16_t);
         status = cairo_truetype_font_allocate_write_buffer (font,
@@ -818,7 +824,7 @@
 	    if (unlikely (status))
 		return _cairo_truetype_font_set_error (font, status);
         }
-        font->base.widths[i] = be16_to_cpu (p[0]);
+        font->widths[i] = be16_to_cpu (p[0]);
     }
 
     return CAIRO_STATUS_SUCCESS;
@@ -845,10 +851,10 @@
 
     if (be16_to_cpu (header.index_to_loc_format) == 0)
     {
-	for (i = 0; i < font->base.num_glyphs + 1; i++)
+	for (i = 0; i < font->num_glyphs + 1; i++)
 	    cairo_truetype_font_write_be16 (font, font->glyphs[i].location / 2);
     } else {
-	for (i = 0; i < font->base.num_glyphs + 1; i++)
+	for (i = 0; i < font->num_glyphs + 1; i++)
 	    cairo_truetype_font_write_be32 (font, font->glyphs[i].location);
     }
 
@@ -876,7 +882,7 @@
     if (unlikely (status))
 	return _cairo_truetype_font_set_error (font, status);
 
-    maxp->num_glyphs = cpu_to_be16 (font->base.num_glyphs);
+    maxp->num_glyphs = cpu_to_be16 (font->num_glyphs);
 
     return CAIRO_STATUS_SUCCESS;
 }
@@ -1020,13 +1026,13 @@
 	                       unsigned short		     glyph,
 			       unsigned short		    *out)
 {
-    if (glyph >= font->num_glyphs_in_face)
+    if (glyph >= font->base.num_glyphs_in_face)
 	return CAIRO_INT_STATUS_UNSUPPORTED;
 
     if (font->parent_to_subset[glyph] == 0) {
-	font->parent_to_subset[glyph] = font->base.num_glyphs;
-	font->glyphs[font->base.num_glyphs].parent_index = glyph;
-	font->base.num_glyphs++;
+	font->parent_to_subset[glyph] = font->num_glyphs;
+	font->glyphs[font->num_glyphs].parent_index = glyph;
+	font->num_glyphs++;
     }
 
     *out = font->parent_to_subset[glyph];
@@ -1179,7 +1185,7 @@
 	goto fail3;
     }
     for (i = 0; i < font->scaled_font_subset->num_glyphs; i++)
-	truetype_subset->widths[i] = (double)font->base.widths[i]/font->base.units_per_em;
+	truetype_subset->widths[i] = (double)font->widths[i]/font->base.units_per_em;
 
     truetype_subset->x_min = (double)font->base.x_min/font->base.units_per_em;
     truetype_subset->y_min = (double)font->base.y_min/font->base.units_per_em;
@@ -1189,7 +1195,7 @@
     truetype_subset->descent = (double)font->base.descent/font->base.units_per_em;
 
     if (length) {
-	truetype_subset->data = malloc (length);
+	truetype_subset->data = _cairo_malloc (length);
 	if (unlikely (truetype_subset->data == NULL)) {
 	    status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
 	    goto fail4;
@@ -1202,7 +1208,7 @@
 
     if (num_strings) {
 	offsets_length = num_strings * sizeof (unsigned long);
-	truetype_subset->string_offsets = malloc (offsets_length);
+	truetype_subset->string_offsets = _cairo_malloc (offsets_length);
 	if (unlikely (truetype_subset->string_offsets == NULL)) {
 	    status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
 	    goto fail5;
@@ -1290,7 +1296,7 @@
 	return CAIRO_INT_STATUS_UNSUPPORTED;
 
     size = be16_to_cpu (map->length);
-    map = malloc (size);
+    map = _cairo_malloc (size);
     if (unlikely (map == NULL))
 	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
@@ -1456,7 +1462,7 @@
 	    if (len > MAX_FONT_NAME_LENGTH)
 		break;
 
-	    str = malloc (len + 1);
+	    str = _cairo_malloc (len + 1);
 	    if (str == NULL)
 		return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
@@ -1482,7 +1488,7 @@
 	for (i = 0; i < u_len; i++)
 	    size += _cairo_ucs4_to_utf8 (be16_to_cpu(u[i]), NULL);
 
-	utf8 = malloc (size + 1);
+	utf8 = _cairo_malloc (size + 1);
 	if (utf8 == NULL) {
 	    status =_cairo_error (CAIRO_STATUS_NO_MEMORY);
 	    goto fail;
@@ -1517,7 +1523,7 @@
 	}
     }
     if (has_tag) {
-	p = malloc (len - 6);
+	p = _cairo_malloc (len - 6);
 	if (unlikely (p == NULL)) {
 	    status =_cairo_error (CAIRO_STATUS_NO_MEMORY);
 	    goto fail;
@@ -1562,7 +1568,7 @@
     if (status)
 	return status;
 
-    name = malloc (size);
+    name = _cairo_malloc (size);
     if (name == NULL)
         return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 

Modified: trunk/Build/source/libs/cairo/cairo-src/src/cairo-type1-fallback.c
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/src/cairo-type1-fallback.c	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/src/cairo-type1-fallback.c	2018-10-20 03:19:36 UTC (rev 48952)
@@ -760,7 +760,7 @@
 
     length = font->header_size + font->data_size +
 	font->trailer_size;
-    type1_subset->data = malloc (length);
+    type1_subset->data = _cairo_malloc (length);
     if (unlikely (type1_subset->data == NULL)) {
         status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
 	goto fail3;

Modified: trunk/Build/source/libs/cairo/cairo-src/src/cairo-type1-subset.c
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/src/cairo-type1-subset.c	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/src/cairo-type1-subset.c	2018-10-20 03:19:36 UTC (rev 48952)
@@ -311,7 +311,7 @@
     const char *decimal_point;
     int decimal_point_len;
 
-    decimal_point = cairo_get_locale_decimal_point ();
+    decimal_point = _cairo_get_locale_decimal_point ();
     decimal_point_len = strlen (decimal_point);
 
     assert (decimal_point_len != 0);
@@ -326,7 +326,7 @@
 	return CAIRO_INT_STATUS_UNSUPPORTED;
 
     s_max = end - start + 5*decimal_point_len + 1;
-    s = malloc (s_max);
+    s = _cairo_malloc (s_max);
     if (unlikely (s == NULL))
 	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
@@ -420,7 +420,7 @@
     while (end > start && _cairo_isspace(end[-1]))
 	end--;
 
-    s = malloc (end - start + 1);
+    s = _cairo_malloc (end - start + 1);
     if (unlikely (s == NULL))
 	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
@@ -624,7 +624,7 @@
     in = (unsigned char *) font->eexec_segment;
     end = (unsigned char *) in + font->eexec_segment_size;
 
-    font->cleartext = malloc (font->eexec_segment_size + 1);
+    font->cleartext = _cairo_malloc (font->eexec_segment_size + 1);
     if (unlikely (font->cleartext == NULL))
 	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
@@ -783,7 +783,7 @@
     const unsigned char *p;
     int command;
 
-    charstring = malloc (encrypted_charstring_length);
+    charstring = _cairo_malloc (encrypted_charstring_length);
     if (unlikely (charstring == NULL))
 	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
@@ -1096,7 +1096,7 @@
     glyph_data_t glyph;
     cairo_status_t status;
 
-    s = malloc (name_length + 1);
+    s = _cairo_malloc (name_length + 1);
     if (unlikely (s == NULL))
 	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
@@ -1285,7 +1285,7 @@
         if (lenIV_end == NULL)
 	    return CAIRO_INT_STATUS_UNSUPPORTED;
 
-        lenIV_str = malloc (lenIV_end - lenIV_start + 1);
+        lenIV_str = _cairo_malloc (lenIV_end - lenIV_start + 1);
         if (unlikely (lenIV_str == NULL))
 	    return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
@@ -1331,7 +1331,7 @@
 
     /* look for "dup" which marks the beginning of the first subr */
     array_start = find_token (subr_count_end, font->cleartext_end, "dup");
-    if (subrs == NULL)
+    if (array_start == NULL)
 	return CAIRO_INT_STATUS_UNSUPPORTED;
 
     /* Read in the subroutines */
@@ -1642,7 +1642,7 @@
 	return CAIRO_INT_STATUS_UNSUPPORTED;
 
     font->type1_length = data_length;
-    font->type1_data = malloc (font->type1_length);
+    font->type1_data = _cairo_malloc (font->type1_length);
     if (unlikely (font->type1_data == NULL))
 	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
@@ -1715,15 +1715,21 @@
 {
     cairo_type1_font_subset_t font;
     cairo_status_t status;
+    cairo_bool_t is_synthetic;
     unsigned long length;
     unsigned int i;
     char buf[30];
 
-    /* We need to use a fallback font generated from the synthesized outlines. */
-    if (scaled_font_subset->scaled_font->backend->is_synthetic &&
-	scaled_font_subset->scaled_font->backend->is_synthetic (scaled_font_subset->scaled_font))
-	return CAIRO_INT_STATUS_UNSUPPORTED;
+    /* We need to use a fallback font if this font differs from the type1 outlines. */
+    if (scaled_font_subset->scaled_font->backend->is_synthetic) {
+	status = scaled_font_subset->scaled_font->backend->is_synthetic (scaled_font_subset->scaled_font, &is_synthetic);
+	if (unlikely (status))
+	    return status;
 
+	if (is_synthetic)
+	    return CAIRO_INT_STATUS_UNSUPPORTED;
+    }
+
     status = _cairo_type1_font_subset_init (&font, scaled_font_subset, hex_encode);
     if (unlikely (status))
 	return status;
@@ -1762,7 +1768,7 @@
     length = font.base.header_size +
 	     font.base.data_size +
 	     font.base.trailer_size;
-    type1_subset->data = malloc (length);
+    type1_subset->data = _cairo_malloc (length);
     if (unlikely (type1_subset->data == NULL))
 	goto fail3;
 

Modified: trunk/Build/source/libs/cairo/cairo-src/src/cairo-type3-glyph-surface.c
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/src/cairo-type3-glyph-surface.c	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/src/cairo-type3-glyph-surface.c	2018-10-20 03:19:36 UTC (rev 48952)
@@ -78,12 +78,11 @@
 				   cairo_bool_t ps)
 {
     cairo_type3_glyph_surface_t *surface;
-    cairo_matrix_t invert_y_axis;
 
     if (unlikely (stream != NULL && stream->status))
 	return _cairo_surface_create_in_error (stream->status);
 
-    surface = malloc (sizeof (cairo_type3_glyph_surface_t));
+    surface = _cairo_malloc (sizeof (cairo_type3_glyph_surface_t));
     if (unlikely (surface == NULL))
 	return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
 
@@ -90,7 +89,8 @@
     _cairo_surface_init (&surface->base,
 			 &cairo_type3_glyph_surface_backend,
 			 NULL, /* device */
-			 CAIRO_CONTENT_COLOR_ALPHA);
+			 CAIRO_CONTENT_COLOR_ALPHA,
+			 TRUE); /* is_vector */
 
     surface->scaled_font = scaled_font;
     surface->stream = stream;
@@ -101,8 +101,6 @@
      * entry in the Type 3 dictionary. In the PDF backend this is an
      * identity matrix. */
     surface->cairo_to_pdf = scaled_font->scale_inverse;
-    cairo_matrix_init_scale (&invert_y_axis, 1, -1);
-    cairo_matrix_multiply (&surface->cairo_to_pdf, &surface->cairo_to_pdf, &invert_y_axis);
 
     _cairo_pdf_operators_init (&surface->pdf_operators,
 			       surface->stream,
@@ -294,15 +292,13 @@
     cairo_type3_glyph_surface_t *surface = abstract_surface;
     cairo_int_status_t status;
     cairo_scaled_font_t *font;
-    cairo_matrix_t new_ctm, invert_y_axis;
+    cairo_matrix_t new_ctm;
 
     status = _cairo_surface_clipper_set_clip (&surface->clipper, clip);
     if (unlikely (status))
 	return status;
 
-    cairo_matrix_init_scale (&invert_y_axis, 1, -1);
-    cairo_matrix_multiply (&new_ctm, &invert_y_axis, &scaled_font->ctm);
-    cairo_matrix_multiply (&new_ctm, &surface->cairo_to_pdf, &new_ctm);
+    cairo_matrix_multiply (&new_ctm, &surface->cairo_to_pdf, &scaled_font->ctm);
     font = cairo_scaled_font_create (scaled_font->font_face,
 				     &scaled_font->font_matrix,
 				     &new_ctm,
@@ -387,14 +383,10 @@
 
     x = _cairo_fixed_to_double (scaled_glyph->bbox.p1.x);
     y = _cairo_fixed_to_double (scaled_glyph->bbox.p2.y);
-    mat.xx = image->width;
-    mat.xy = 0;
-    mat.yx = 0;
-    mat.yy = image->height;
-    mat.x0 = x;
-    mat.y0 = y;
+    cairo_matrix_init(&mat, image->width, 0,
+		      0, -image->height,
+		      x, y);
     cairo_matrix_multiply (&mat, &mat, &surface->scaled_font->scale_inverse);
-    mat.y0 *= -1;
 
     return _cairo_type3_glyph_surface_emit_image (surface, image, &mat);
 }
@@ -523,9 +515,9 @@
 				 "%f 0 %f %f %f %f d1\n",
                                  x_advance,
 				 _cairo_fixed_to_double (bbox->p1.x),
-				 - _cairo_fixed_to_double (bbox->p2.y),
+				 _cairo_fixed_to_double (bbox->p1.y),
 				 _cairo_fixed_to_double (bbox->p2.x),
-				 - _cairo_fixed_to_double (bbox->p1.y));
+				 _cairo_fixed_to_double (bbox->p2.y));
 
     if (status == CAIRO_INT_STATUS_SUCCESS) {
 	cairo_output_stream_t *mem_stream;

Modified: trunk/Build/source/libs/cairo/cairo-src/src/cairo-types-private.h
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/src/cairo-types-private.h	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/src/cairo-types-private.h	2018-10-20 03:19:36 UTC (rev 48952)
@@ -194,6 +194,7 @@
     cairo_hint_style_t hint_style;
     cairo_hint_metrics_t hint_metrics;
     cairo_round_glyph_positions_t round_glyph_positions;
+    char *variations;
 };
 
 struct _cairo_glyph_text_info {

Modified: trunk/Build/source/libs/cairo/cairo-src/src/cairo-unicode.c
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/src/cairo-unicode.c	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/src/cairo-unicode.c	2018-10-20 03:19:36 UTC (rev 48952)
@@ -342,6 +342,36 @@
     return bytes;
 }
 
+/**
+ * _cairo_ucs4_to_utf16:
+ * @unicode: a UCS-4 character
+ * @utf16: buffer to write utf16 string into. Must have at least 2
+ * elements. Or %NULL.
+ *
+ * This space left intentionally blank.
+ *
+ * Return value: Number of elements in the utf16 string or 0 if an
+ * invalid unicode character
+ **/
+int
+_cairo_ucs4_to_utf16 (uint32_t  unicode,
+		      uint16_t *utf16)
+{
+    if (unicode < 0x10000) {
+	if (utf16)
+	    utf16[0] = unicode;
+	return 1;
+    } else if (unicode < 0x110000) {
+	if (utf16) {
+	    utf16[0] = (unicode - 0x10000) / 0x400 + 0xd800;
+	    utf16[1] = (unicode - 0x10000) % 0x400 + 0xdc00;
+	}
+	return 2;
+    } else {
+	return 0;
+    }
+}
+
 #if CAIRO_HAS_UTF8_TO_UTF16
 /**
  * _cairo_utf8_to_utf16:
@@ -401,12 +431,7 @@
     for (i = 0; i < n16;) {
 	uint32_t wc = _utf8_get_char (in);
 
-	if (wc < 0x10000) {
-	    str16[i++] = wc;
-	} else {
-	    str16[i++] = (wc - 0x10000) / 0x400 + 0xd800;
-	    str16[i++] = (wc - 0x10000) % 0x400 + 0xdc00;
-	}
+	i += _cairo_ucs4_to_utf16 (wc, str16 + i);
 
 	in = UTF8_NEXT_CHAR (in);
     }

Modified: trunk/Build/source/libs/cairo/cairo-src/src/cairo-user-font.c
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/src/cairo-user-font.c	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/src/cairo-user-font.c	2018-10-20 03:19:36 UTC (rev 48952)
@@ -402,7 +402,7 @@
 
     font_face->immutable = TRUE;
 
-    user_scaled_font = malloc (sizeof (cairo_user_scaled_font_t));
+    user_scaled_font = _cairo_malloc (sizeof (cairo_user_scaled_font_t));
     if (unlikely (user_scaled_font == NULL))
 	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
@@ -544,7 +544,7 @@
 {
     cairo_user_font_face_t *font_face;
 
-    font_face = malloc (sizeof (cairo_user_font_face_t));
+    font_face = _cairo_malloc (sizeof (cairo_user_font_face_t));
     if (!font_face) {
 	_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
 	return (cairo_font_face_t *)&_cairo_font_face_nil;

Modified: trunk/Build/source/libs/cairo/cairo-src/src/cairo-version.c
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/src/cairo-version.c	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/src/cairo-version.c	2018-10-20 03:19:36 UTC (rev 48952)
@@ -115,8 +115,8 @@
  * <informalexample><screen>
  * Compile-time
  * ------------
- * CAIRO_VERSION_STRING    Human-readable
- * CAIRO_VERSION           Encoded, suitable for comparison
+ * #CAIRO_VERSION_STRING   Human-readable
+ * #CAIRO_VERSION          Encoded, suitable for comparison
  *  
  * Run-time
  * --------

Modified: trunk/Build/source/libs/cairo/cairo-src/src/cairo-vg-surface.c
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/src/cairo-vg-surface.c	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/src/cairo-vg-surface.c	2018-10-20 03:19:36 UTC (rev 48952)
@@ -1517,7 +1517,7 @@
 {
     cairo_vg_surface_t *surface;
 
-    surface = malloc (sizeof (cairo_vg_surface_t));
+    surface = _cairo_malloc (sizeof (cairo_vg_surface_t));
     if (unlikely (surface == NULL))
 	return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
 
@@ -1529,7 +1529,8 @@
     _cairo_surface_init (&surface->base,
 			 &cairo_vg_surface_backend,
 			 NULL, /* device */
-			 _vg_format_to_content (format));
+			 _vg_format_to_content (format),
+			 FALSE); /* is_vector */
 
     surface->width  = width;
     surface->height = height;
@@ -1711,7 +1712,7 @@
     cairo_vg_context_t *context;
     cairo_status_t status;
 
-    context = malloc (sizeof (*context));
+    context = _cairo_malloc (sizeof (*context));
     if (unlikely (context == NULL))
 	return (cairo_vg_context_t *) &_vg_context_nil;
 
@@ -1816,7 +1817,7 @@
     cairo_vg_context_t *context;
     cairo_status_t status;
 
-    context = malloc (sizeof (*context));
+    context = _cairo_malloc (sizeof (*context));
     if (unlikely (context == NULL))
 	return (cairo_vg_context_t *) &_vg_context_nil;
 

Modified: trunk/Build/source/libs/cairo/cairo-src/src/cairo-vg.h
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/src/cairo-vg.h	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/src/cairo-vg.h	2018-10-20 03:19:36 UTC (rev 48952)
@@ -1,8 +1,8 @@
 /* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */
 /* cairo - a vector graphics library with display and print output
  *
- * Copyright \xA9 2007 * Mozilla Corporation
- * Copyright \xA9 2009 Chris Wilson
+ * Copyright © 2007 * Mozilla Corporation
+ * Copyright © 2009 Chris Wilson
  *
  * This library is free software; you can redistribute it and/or
  * modify it either under the terms of the GNU Lesser General Public

Modified: trunk/Build/source/libs/cairo/cairo-src/src/cairo-win32.h
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/src/cairo-win32.h	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/src/cairo-win32.h	2018-10-20 03:19:36 UTC (rev 48952)
@@ -49,6 +49,10 @@
 cairo_win32_surface_create (HDC hdc);
 
 cairo_public cairo_surface_t *
+cairo_win32_surface_create_with_format (HDC hdc,
+                                        cairo_format_t format);
+
+cairo_public cairo_surface_t *
 cairo_win32_printing_surface_create (HDC hdc);
 
 cairo_public cairo_surface_t *

Modified: trunk/Build/source/libs/cairo/cairo-src/src/cairo-xcb-connection.c
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/src/cairo-xcb-connection.c	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/src/cairo-xcb-connection.c	2018-10-20 03:19:36 UTC (rev 48952)
@@ -111,7 +111,7 @@
 		cairo_xcb_xrender_format_t *f;
 		cairo_status_t status;
 
-		f = malloc (sizeof (cairo_xcb_xrender_format_t));
+		f = _cairo_malloc (sizeof (cairo_xcb_xrender_format_t));
 		if (unlikely (f == NULL))
 		    return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
@@ -177,7 +177,7 @@
 	    if (! _cairo_hash_table_lookup (connection->xrender_formats, &key)) {
 		cairo_xcb_xrender_format_t *f;
 
-		f = malloc (sizeof (cairo_xcb_xrender_format_t));
+		f = _cairo_malloc (sizeof (cairo_xcb_xrender_format_t));
 		if (unlikely (f == NULL))
 		    return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
@@ -634,7 +634,7 @@
 	}
     }
 
-    connection = malloc (sizeof (cairo_xcb_connection_t));
+    connection = _cairo_malloc (sizeof (cairo_xcb_connection_t));
     if (unlikely (connection == NULL))
 	goto unlock;
 

Modified: trunk/Build/source/libs/cairo/cairo-src/src/cairo-xcb-screen.c
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/src/cairo-xcb-screen.c	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/src/cairo-xcb-screen.c	2018-10-20 03:19:36 UTC (rev 48952)
@@ -249,7 +249,7 @@
 	}
     }
 
-    screen = malloc (sizeof (cairo_xcb_screen_t));
+    screen = _cairo_malloc (sizeof (cairo_xcb_screen_t));
     if (unlikely (screen == NULL))
 	goto unlock;
 

Modified: trunk/Build/source/libs/cairo/cairo-src/src/cairo-xcb-shm.c
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/src/cairo-xcb-shm.c	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/src/cairo-xcb-shm.c	2018-10-20 03:19:36 UTC (rev 48952)
@@ -209,7 +209,7 @@
 	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
     }
 
-    pool = malloc (sizeof (cairo_xcb_shm_mem_pool_t));
+    pool = _cairo_malloc (sizeof (cairo_xcb_shm_mem_pool_t));
     if (unlikely (pool == NULL)) {
 	CAIRO_MUTEX_UNLOCK (connection->shm_mutex);
 	return _cairo_error (CAIRO_STATUS_NO_MEMORY);

Modified: trunk/Build/source/libs/cairo/cairo-src/src/cairo-xcb-surface-core.c
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/src/cairo-xcb-surface-core.c	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/src/cairo-xcb-surface-core.c	2018-10-20 03:19:36 UTC (rev 48952)
@@ -85,7 +85,7 @@
 {
     cairo_xcb_pixmap_t *surface;
 
-    surface = malloc (sizeof (cairo_xcb_pixmap_t));
+    surface = _cairo_malloc (sizeof (cairo_xcb_pixmap_t));
     if (unlikely (surface == NULL))
 	return (cairo_xcb_pixmap_t *)
 	    _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
@@ -93,7 +93,8 @@
     _cairo_surface_init (&surface->base,
 			 &_cairo_xcb_pixmap_backend,
 			 NULL,
-			 target->base.content);
+			 target->base.content,
+			 FALSE); /* is_vector */
 
     surface->connection = target->connection;
     surface->screen = target->screen;
@@ -118,7 +119,7 @@
 {
     cairo_xcb_pixmap_t *surface;
 
-    surface = malloc (sizeof (cairo_xcb_pixmap_t));
+    surface = _cairo_malloc (sizeof (cairo_xcb_pixmap_t));
     if (unlikely (surface == NULL))
 	return (cairo_xcb_pixmap_t *)
 	    _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
@@ -126,7 +127,8 @@
     _cairo_surface_init (&surface->base,
 			 &_cairo_xcb_pixmap_backend,
 			 NULL,
-			 target->base.content);
+			 target->base.content,
+			 FALSE); /* is_vector */
 
     surface->connection = target->connection;
     surface->screen = target->screen;

Modified: trunk/Build/source/libs/cairo/cairo-src/src/cairo-xcb-surface-render.c
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/src/cairo-xcb-surface-render.c	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/src/cairo-xcb-surface-render.c	2018-10-20 03:19:36 UTC (rev 48952)
@@ -114,7 +114,7 @@
 {
     cairo_xcb_picture_t *surface;
 
-    surface = malloc (sizeof (cairo_xcb_picture_t));
+    surface = _cairo_malloc (sizeof (cairo_xcb_picture_t));
     if (unlikely (surface == NULL))
 	return (cairo_xcb_picture_t *)
 	    _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
@@ -122,7 +122,8 @@
     _cairo_surface_init (&surface->base,
 			 &_cairo_xcb_picture_backend,
 			 &screen->connection->device,
-			 _cairo_content_from_pixman_format (pixman_format));
+			 _cairo_content_from_pixman_format (pixman_format),
+			 FALSE); /* is_vector */
 
     cairo_list_add (&surface->link, &screen->pictures);
 
@@ -4140,7 +4141,7 @@
     cairo_xcb_font_t	*priv;
     int i;
 
-    priv = malloc (sizeof (cairo_xcb_font_t));
+    priv = _cairo_malloc (sizeof (cairo_xcb_font_t));
     if (unlikely (priv == NULL))
 	return NULL;
 
@@ -4333,7 +4334,7 @@
 	}
 
 	if (to_free == NULL) {
-	    to_free = malloc (sizeof (cairo_xcb_font_glyphset_free_glyphs_t));
+	    to_free = _cairo_malloc (sizeof (cairo_xcb_font_glyphset_free_glyphs_t));
 	    if (unlikely (to_free == NULL)) {
 		_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
 		return; /* XXX cannot propagate failure */
@@ -4360,7 +4361,7 @@
 {
     cairo_xcb_glyph_private_t *priv;
 
-    priv = malloc (sizeof (*priv));
+    priv = _cairo_malloc (sizeof (*priv));
     if (unlikely (priv == NULL))
 	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
@@ -4471,7 +4472,7 @@
 	    if (c == 0)
 		break;
 
-	    new = malloc (c);
+	    new = _cairo_malloc (c);
 	    if (unlikely (new == NULL)) {
 		status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
 		goto BAIL;
@@ -4502,7 +4503,7 @@
 	    if (c == 0)
 		break;
 
-	    new = malloc (4 * c);
+	    new = _cairo_malloc (4 * c);
 	    if (unlikely (new == NULL)) {
 		status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
 		goto BAIL;
@@ -4584,7 +4585,7 @@
     int i;
 
     if (estimated_req_size > ARRAY_LENGTH (stack_buf)) {
-	buf = malloc (estimated_req_size);
+	buf = _cairo_malloc (estimated_req_size);
 	if (unlikely (buf == NULL))
 	    return _cairo_error (CAIRO_STATUS_NO_MEMORY);
     }

Modified: trunk/Build/source/libs/cairo/cairo-src/src/cairo-xcb-surface.c
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/src/cairo-xcb-surface.c	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/src/cairo-xcb-surface.c	2018-10-20 03:19:36 UTC (rev 48952)
@@ -1075,7 +1075,7 @@
 {
     cairo_xcb_surface_t *surface;
 
-    surface = malloc (sizeof (cairo_xcb_surface_t));
+    surface = _cairo_malloc (sizeof (cairo_xcb_surface_t));
     if (unlikely (surface == NULL))
 	return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
 
@@ -1082,7 +1082,8 @@
     _cairo_surface_init (&surface->base,
 			 &_cairo_xcb_surface_backend,
 			 &screen->connection->device,
-			 _cairo_content_from_pixman_format (pixman_format));
+			 _cairo_content_from_pixman_format (pixman_format),
+			 FALSE); /* is_vector */
 
     surface->connection = _cairo_xcb_connection_reference (screen->connection);
     surface->screen = screen;

Modified: trunk/Build/source/libs/cairo/cairo-src/src/cairo-xlib-core-compositor.c
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/src/cairo-xlib-core-compositor.c	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/src/cairo-xlib-core-compositor.c	2018-10-20 03:19:36 UTC (rev 48952)
@@ -632,9 +632,10 @@
 const cairo_compositor_t *
 _cairo_xlib_core_compositor_get (void)
 {
+    static cairo_atomic_once_t once = CAIRO_ATOMIC_ONCE_INIT;
     static cairo_compositor_t compositor;
 
-    if (compositor.delegate == NULL) {
+    if (_cairo_atomic_init_once_enter(&once)) {
 	compositor.delegate = _cairo_xlib_fallback_compositor_get ();
 
 	compositor.paint = _cairo_xlib_core_compositor_paint;
@@ -642,6 +643,8 @@
 	compositor.fill  = _cairo_xlib_core_compositor_fill;
 	compositor.stroke = _cairo_xlib_core_compositor_stroke;
 	compositor.glyphs = NULL; /* XXX PolyGlyph? */
+
+	_cairo_atomic_init_once_leave(&once);
     }
 
     return &compositor;

Modified: trunk/Build/source/libs/cairo/cairo-src/src/cairo-xlib-display.c
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/src/cairo-xlib-display.c	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/src/cairo-xlib-display.c	2018-10-20 03:19:36 UTC (rev 48952)
@@ -207,7 +207,7 @@
 	}
     }
 
-    display = malloc (sizeof (cairo_xlib_display_t));
+    display = _cairo_malloc (sizeof (cairo_xlib_display_t));
     if (unlikely (display == NULL)) {
 	device = _cairo_device_create_in_error (CAIRO_STATUS_NO_MEMORY);
 	goto UNLOCK;

Modified: trunk/Build/source/libs/cairo/cairo-src/src/cairo-xlib-private.h
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/src/cairo-xlib-private.h	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/src/cairo-xlib-private.h	2018-10-20 03:19:36 UTC (rev 48952)
@@ -104,7 +104,7 @@
      * We also use this variable as a guard against a second
      * independent bug with transformed repeating pictures:
      *
-     * http://lists.freedesktop.org/archives/cairo/2004-September/001839.html
+     * https://lists.freedesktop.org/archives/cairo/2004-September/001839.html
      *
      * Both are fixed in xorg >= 6.9 and hopefully in > 6.8.2, so
      * we can reuse the test for now.

Modified: trunk/Build/source/libs/cairo/cairo-src/src/cairo-xlib-render-compositor.c
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/src/cairo-xlib-render-compositor.c	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/src/cairo-xlib-render-compositor.c	2018-10-20 03:19:36 UTC (rev 48952)
@@ -965,7 +965,7 @@
     cairo_list_del (&priv->link);
 
     status = _cairo_xlib_display_acquire (priv->device, &display);
-    if (status)
+    if (unlikely (status)) /* this should be impossible but leak just in case */
 	goto BAIL;
 
     for (i = 0; i < NUM_GLYPHSETS; i++) {
@@ -978,7 +978,7 @@
 
     cairo_device_release (&display->base);
 BAIL:
-    cairo_device_destroy (&display->base);
+    cairo_device_destroy (priv->device);
     free (priv);
 }
 
@@ -989,7 +989,7 @@
     cairo_xlib_font_t *priv;
     int i;
 
-    priv = malloc (sizeof (cairo_xlib_font_t));
+    priv = _cairo_malloc (sizeof (cairo_xlib_font_t));
     if (unlikely (priv == NULL))
 	return NULL;
 
@@ -1089,7 +1089,7 @@
 {
     cairo_xlib_glyph_private_t *priv;
 
-    priv = malloc (sizeof (*priv));
+    priv = _cairo_malloc (sizeof (*priv));
     if (unlikely (priv == NULL))
 	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
@@ -1290,7 +1290,7 @@
 	    if (c == 0)
 		break;
 
-	    new = malloc (c);
+	    new = _cairo_malloc (c);
 	    if (!new) {
 		status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
 		goto BAIL;
@@ -1318,7 +1318,7 @@
 	    if (c == 0)
 		break;
 
-	    new = malloc (4 * c);
+	    new = _cairo_malloc (4 * c);
 	    if (unlikely (new == NULL)) {
 		status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
 		goto BAIL;
@@ -1725,9 +1725,10 @@
 const cairo_compositor_t *
 _cairo_xlib_mask_compositor_get (void)
 {
+    static cairo_atomic_once_t once = CAIRO_ATOMIC_ONCE_INIT;
     static cairo_mask_compositor_t compositor;
 
-    if (compositor.base.delegate == NULL) {
+    if (_cairo_atomic_init_once_enter(&once)) {
 	_cairo_mask_compositor_init (&compositor,
 				     _cairo_xlib_fallback_compositor_get ());
 
@@ -1745,6 +1746,8 @@
 	compositor.composite_boxes = composite_boxes;
 	compositor.check_composite_glyphs = check_composite_glyphs;
 	compositor.composite_glyphs = composite_glyphs;
+
+	_cairo_atomic_init_once_leave(&once);
     }
 
     return &compositor.base;
@@ -1827,6 +1830,9 @@
 
     //X_DEBUG ((display->display, "composite_trapezoids (dst=%x)", (unsigned int) dst->drawable));
 
+    if (traps->num_traps == 0)
+	return CAIRO_STATUS_SUCCESS;
+
     if (dst->base.is_clear &&
 	(op == CAIRO_OPERATOR_OVER || op == CAIRO_OPERATOR_ADD))
     {
@@ -1973,9 +1979,10 @@
 const cairo_compositor_t *
 _cairo_xlib_traps_compositor_get (void)
 {
+    static cairo_atomic_once_t once = CAIRO_ATOMIC_ONCE_INIT;
     static cairo_traps_compositor_t compositor;
 
-    if (compositor.base.delegate == NULL) {
+    if (_cairo_atomic_init_once_enter(&once)) {
 	_cairo_traps_compositor_init (&compositor,
 				      _cairo_xlib_mask_compositor_get ());
 
@@ -1997,6 +2004,8 @@
 	compositor.composite_tristrip = composite_tristrip;
 	compositor.check_composite_glyphs = check_composite_glyphs;
 	compositor.composite_glyphs = composite_glyphs;
+
+	_cairo_atomic_init_once_leave(&once);
     }
 
     return &compositor.base;

Modified: trunk/Build/source/libs/cairo/cairo-src/src/cairo-xlib-screen.c
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/src/cairo-xlib-screen.c	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/src/cairo-xlib-screen.c	2018-10-20 03:19:36 UTC (rev 48952)
@@ -330,7 +330,7 @@
 	goto CLEANUP_DISPLAY;
     }
 
-    info = malloc (sizeof (cairo_xlib_screen_t));
+    info = _cairo_malloc (sizeof (cairo_xlib_screen_t));
     if (unlikely (info == NULL)) {
 	status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
 	goto CLEANUP_DISPLAY;

Modified: trunk/Build/source/libs/cairo/cairo-src/src/cairo-xlib-source.c
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/src/cairo-xlib-source.c	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/src/cairo-xlib-source.c	2018-10-20 03:19:36 UTC (rev 48952)
@@ -109,7 +109,7 @@
     if (picture == None)
 	return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
 
-    source = malloc (sizeof (*source));
+    source = _cairo_malloc (sizeof (*source));
     if (unlikely (source == NULL)) {
 	XRenderFreePicture (dst->display->display, picture);
 	if (pixmap)
@@ -120,7 +120,8 @@
     _cairo_surface_init (&source->base,
 			 &cairo_xlib_source_backend,
 			 NULL, /* device */
-			 CAIRO_CONTENT_COLOR_ALPHA);
+			 CAIRO_CONTENT_COLOR_ALPHA,
+			 FALSE); /* is_vector */
 
     /* The source exists only within an operation */
     source->picture = picture;
@@ -626,7 +627,8 @@
 	_cairo_surface_init (&source->base,
 			     &cairo_xlib_source_backend,
 			     NULL, /* device */
-			     CAIRO_CONTENT_COLOR_ALPHA);
+			     CAIRO_CONTENT_COLOR_ALPHA,
+			     FALSE); /* is_vector */
 
 	pa.subwindow_mode = IncludeInferiors;
 	source->picture = XRenderCreatePicture (dpy,
@@ -964,7 +966,7 @@
 	_cairo_xlib_shm_surface_get_pixmap (src)) {
 	cairo_xlib_proxy_t *proxy;
 
-	proxy = malloc (sizeof(*proxy));
+	proxy = _cairo_malloc (sizeof(*proxy));
 	if (unlikely (proxy == NULL))
 	    return _cairo_surface_create_in_error (CAIRO_STATUS_NO_MEMORY);
 
@@ -971,7 +973,8 @@
 	_cairo_surface_init (&proxy->source.base,
 			     &cairo_xlib_proxy_backend,
 			     dst->base.device,
-			     src->content);
+			     src->content,
+			     src->is_vector);
 
 	proxy->source.dpy = dst->display->display;
 	proxy->source.picture = XRenderCreatePicture (proxy->source.dpy,

Modified: trunk/Build/source/libs/cairo/cairo-src/src/cairo-xlib-surface-shm.c
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/src/cairo-xlib-surface-shm.c	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/src/cairo-xlib-surface-shm.c	2018-10-20 03:19:36 UTC (rev 48952)
@@ -573,7 +573,7 @@
     size_t bytes, maxbits = 16, minbits = MIN_BITS;
     Status success;
 
-    pool = malloc (sizeof (cairo_xlib_shm_t));
+    pool = _cairo_malloc (sizeof (cairo_xlib_shm_t));
     if (pool == NULL)
 	return NULL;
 
@@ -650,7 +650,7 @@
 
     assert (mem != NULL);
 
-    info = malloc (sizeof (*info));
+    info = _cairo_malloc (sizeof (*info));
     if (info == NULL) {
 	_cairo_mempool_free (&pool->mem, mem);
 	return NULL;
@@ -814,7 +814,7 @@
     if (size < MIN_SIZE)
 	return NULL;
 
-    shm = malloc (sizeof (*shm));
+    shm = _cairo_malloc (sizeof (*shm));
     if (unlikely (shm == NULL))
 	return (cairo_xlib_shm_surface_t *)_cairo_surface_create_in_error (CAIRO_STATUS_NO_MEMORY);
 
@@ -821,7 +821,8 @@
     _cairo_surface_init (&shm->image.base,
 			 &cairo_xlib_shm_surface_backend,
 			 other->base.device,
-			 _cairo_content_from_pixman_format (format));
+			 _cairo_content_from_pixman_format (format),
+			 FALSE); /* is_vector */
 
     if (_cairo_xlib_display_acquire (other->base.device, &display))
 	goto cleanup_shm;
@@ -1386,7 +1387,7 @@
     if (!can_use_shm (display->display, &has_pixmap))
 	return;
 
-    shm = malloc (sizeof (*shm));
+    shm = _cairo_malloc (sizeof (*shm));
     if (unlikely (shm == NULL))
 	return;
 

Modified: trunk/Build/source/libs/cairo/cairo-src/src/cairo-xlib-surface.c
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/src/cairo-xlib-surface.c	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/src/cairo-xlib-surface.c	2018-10-20 03:19:36 UTC (rev 48952)
@@ -189,12 +189,6 @@
 
 #define CAIRO_ASSUME_PIXMAP	20
 
-static const XTransform identity = { {
-    { 1 << 16, 0x00000, 0x00000 },
-    { 0x00000, 1 << 16, 0x00000 },
-    { 0x00000, 0x00000, 1 << 16 },
-} };
-
 static Visual *
 _visual_for_xrender_format(Screen *screen,
 			   XRenderPictFormat *xrender_format)
@@ -1772,7 +1766,7 @@
 	;
     }
 
-    surface = malloc (sizeof (cairo_xlib_surface_t));
+    surface = _cairo_malloc (sizeof (cairo_xlib_surface_t));
     if (unlikely (surface == NULL))
 	return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
 
@@ -1800,7 +1794,8 @@
     _cairo_surface_init (&surface->base,
 			 &cairo_xlib_surface_backend,
 			 screen->device,
-			 _xrender_format_to_content (xrender_format));
+			 _xrender_format_to_content (xrender_format),
+			 FALSE); /* is_vector */
 
     surface->screen = screen;
     surface->compositor = display->compositor;
@@ -1891,7 +1886,7 @@
     /* Note: the minimum surface size allowed in the X protocol is 1x1.
      * However, as we historically did not check the minimum size we
      * allowed applications to lie and set the correct size later (one hopes).
-     * To preserve compatability we must allow applications to use
+     * To preserve compatibility we must allow applications to use
      * 0x0 surfaces.
      */
     return (width  >= 0 && width  <= XLIB_COORD_MAX &&

Modified: trunk/Build/source/libs/cairo/cairo-src/src/cairo-xlib-visual.c
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/src/cairo-xlib-visual.c	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/src/cairo-xlib-visual.c	2018-10-20 03:19:36 UTC (rev 48952)
@@ -82,7 +82,7 @@
     for (i = 0; i < RAMP_SIZE; i++)
 	ramp_index_to_short[i] = (0xffff * i + ((RAMP_SIZE-1)>>1)) / (RAMP_SIZE-1);
 
-    info = malloc (sizeof (cairo_xlib_visual_info_t));
+    info = _cairo_malloc (sizeof (cairo_xlib_visual_info_t));
     if (unlikely (info == NULL))
 	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 

Modified: trunk/Build/source/libs/cairo/cairo-src/src/cairo-xlib-xcb-surface.c
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/src/cairo-xlib-xcb-surface.c	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/src/cairo-xlib-xcb-surface.c	2018-10-20 03:19:36 UTC (rev 48952)
@@ -391,7 +391,7 @@
 	}
     }
 
-    display = malloc (sizeof (cairo_xlib_xcb_display_t));
+    display = _cairo_malloc (sizeof (cairo_xlib_xcb_display_t));
     if (unlikely (display == NULL)) {
 	device = _cairo_device_create_in_error (CAIRO_STATUS_NO_MEMORY);
 	goto unlock;
@@ -438,7 +438,7 @@
     if (unlikely (xcb->status))
 	return xcb;
 
-    surface = malloc (sizeof (*surface));
+    surface = _cairo_malloc (sizeof (*surface));
     if (unlikely (surface == NULL)) {
 	cairo_surface_destroy (xcb);
 	return _cairo_surface_create_in_error (CAIRO_STATUS_NO_MEMORY);
@@ -447,7 +447,8 @@
     _cairo_surface_init (&surface->base,
 			 &_cairo_xlib_xcb_surface_backend,
 			 _cairo_xlib_xcb_device_create (dpy, xcb->device),
-			 xcb->content);
+			 xcb->content,
+			 FALSE); /* is_vector */
 
     /* _cairo_surface_init() got another reference to the device, drop ours */
     cairo_device_destroy (surface->base.device);

Modified: trunk/Build/source/libs/cairo/cairo-src/src/cairo-xml-surface.c
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/src/cairo-xml-surface.c	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/src/cairo-xml-surface.c	2018-10-20 03:19:36 UTC (rev 48952)
@@ -36,7 +36,7 @@
 
 /* This surface is intended to produce a verbose, hierarchical, DAG XML file
  * representing a single surface. It is intended to be used by debuggers,
- * such as cairo-sphinx, or by application test-suites that what a log of
+ * such as cairo-sphinx, or by application test-suites that want a log of
  * operations.
  */
 
@@ -258,7 +258,7 @@
 {
     cairo_xml_t *xml;
 
-    xml = malloc (sizeof (cairo_xml_t));
+    xml = _cairo_malloc (sizeof (cairo_xml_t));
     if (unlikely (xml == NULL))
 	return _cairo_device_create_in_error (CAIRO_STATUS_NO_MEMORY);
 
@@ -933,7 +933,7 @@
     if (unlikely (status))
 	return status;
 
-    buf = malloc (size);
+    buf = _cairo_malloc (size);
     if (unlikely (buf == NULL))
 	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
@@ -1098,7 +1098,7 @@
 {
     cairo_xml_surface_t *surface;
 
-    surface = malloc (sizeof (cairo_xml_surface_t));
+    surface = _cairo_malloc (sizeof (cairo_xml_surface_t));
     if (unlikely (surface == NULL))
 	return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
 
@@ -1105,7 +1105,8 @@
     _cairo_surface_init (&surface->base,
 			 &_cairo_xml_surface_backend,
 			 device,
-			 content);
+			 content,
+			 TRUE); /* is_vector */
 
     surface->width = width;
     surface->height = height;

Modified: trunk/Build/source/libs/cairo/cairo-src/src/cairo.c
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/src/cairo.c	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/src/cairo.c	2018-10-20 03:19:36 UTC (rev 48952)
@@ -107,6 +107,221 @@
  * space</firstterm>.
  **/
 
+/**
+ * SECTION:cairo-tag
+ * @Title: Tags and Links
+ * @Short_Description: Hyperlinks and document structure
+ * @See_Also: #cairo_pdf_surface_t
+ *
+ * The tag functions provide the ability to specify hyperlinks and
+ * document logical structure on supported backends. The following tags are supported:
+ * * [Link][link] - Create a hyperlink
+ * * [Destinations][dest] - Create a hyperlink destination
+ * * [Document Structure Tags][doc-struct] - Create PDF Document Structure
+ *
+ * # Link Tags # {#link}
+ * A hyperlink is specified by enclosing the hyperlink text with the %CAIRO_TAG_LINK tag.
+ *
+ * For example:
+ * <informalexample><programlisting>
+ * cairo_tag_begin (cr, CAIRO_TAG_LINK, "uri='https://cairographics.org'");
+ * cairo_move_to (cr, 50, 50);
+ * cairo_show_text (cr, "This is a link to the cairo website.");
+ * cairo_tag_end (cr, CAIRO_TAG_LINK);
+ * </programlisting></informalexample>
+ *
+ * The PDF backend uses one or more rectangles to define the clickable
+ * area of the link.  By default cairo will use the extents of the
+ * drawing operations enclosed by the begin/end link tags to define the
+ * clickable area. In some cases, such as a link split across two
+ * lines, the default rectangle is undesirable.
+ *
+ * @rect: [optional] The "rect" attribute allows the application to
+ * specify one or more rectangles that form the clickable region.  The
+ * value of this attribute is an array of floats. Each rectangle is
+ * specified by four elements in the array: x, y, width, height. The
+ * array size must be a multiple of four.
+ *
+ * An example of creating a link with user specified clickable region:
+ * <informalexample><programlisting>
+ * cairo_font_extents_t font_extents;
+ * cairo_text_extents_t text1_extents;
+ * cairo_text_extents_t text2_extents;
+ * char attribs[100];
+ * const char *text1 = "This link is split";
+ * const char *text2 = "across two lines";
+ *
+ * cairo_font_extents (cr, &font_extents);
+ * cairo_move_to (cr, 450, 50);
+ * cairo_text_extents (cr, text1, &text1_extents);
+ * cairo_move_to (cr, 50, 70);
+ * cairo_text_extents (cr, text2, &text2_extents);
+ * sprintf (attribs,
+ *          "rect=[%f %f %f %f %f %f %f %f] uri='https://cairographics.org'",
+ *          text1_extents.x_bearing,
+ *          text1_extents.y_bearing,
+ *          text1_extents.width,
+ *          text1_extents.height,
+ *          text2_extents.x_bearing,
+ *          text2_extents.y_bearing,
+ *          text2_extents.width,
+ *          text2_extents.height);
+ *
+ * cairo_tag_begin (cr, CAIRO_TAG_LINK, attribs);
+ * cairo_show_text (cr, "This is a link to the cairo website");
+ * cairo_move_to (cr, 450, 50);
+ * cairo_show_text (cr, text1);
+ * cairo_move_to (cr, 50, 70);
+ * cairo_show_text (cr, text2);
+ * cairo_tag_end (cr, CAIRO_TAG_LINK);
+ * </programlisting></informalexample>
+ *
+ * There are three types of links. Each type has its own attributes as detailed below.
+ * * [Internal Links][internal-link] - A link to a location in the same document
+ * * [URI Links][uri-link] - A link to a Uniform resource identifier
+ * * [File Links][file-link] - A link to a location in another document
+ *
+ * ## Internal Links ## {#internal-link}
+ * An internal link is a link to a location in the same document. The destination
+ * is specified with either:
+ *
+ * @dest: a UTF-8 string specifying the destination in the PDF file to link
+ * to. Destinations are created with the %CAIRO_TAG_DEST tag.
+ *
+ * or the two attributes:
+ *
+ * @page: An integer specifying the page number in the PDF file to link to.
+ *
+ * @pos: [optional] An array of two floats specifying the x,y position
+ * on the page.
+ *
+ * An example of the link attributes to link to a page and x,y position:
+ * <programlisting>
+ * "page=3 pos=[3.1 6.2]"
+ * </programlisting>
+ *
+ * ## URI Links ## {#uri-link}
+ * A URI link is a link to a Uniform Resource Identifier ([RFC 2396](http://tools.ietf.org/html/rfc2396)).
+ *
+ * A URI is specified with the following attribute:
+ *
+ * @uri: An ASCII string specifying the URI.
+ *
+ * An example of the link attributes to the cairo website:
+ * <programlisting>
+ * "uri='https://cairographics.org'"
+ * </programlisting>
+ *
+ * ## File Links ## {#file-link}
+ * A file link is a link a location in another PDF file.
+ *
+ * The file attribute (required) specifies the name of the PDF file:
+ *
+ * @file: File name of PDF file to link to.
+ *
+ * The position is specified by either:
+ *
+ *  @dest: a UTF-8 string specifying the named destination in the PDF file.
+ *
+ * or
+ *
+ *  @page: An integer specifying the page number in the PDF file.
+ *
+ *  @pos: [optional] An array of two floats specifying the x,y
+ *  position on the page. Position coordinates in external files are in PDF
+ *  coordinates (0,0 at bottom left).
+ *
+ * An example of the link attributes to PDF file:
+ * <programlisting>
+ * "file='document.pdf' page=16 pos=[25 40]"
+ * </programlisting>
+ *
+ * # Destination Tags # {#dest}
+ *
+ * A destination is specified by enclosing the destination drawing
+ * operations with the %CAIRO_TAG_DEST tag.
+ *
+ * @name: [required] A UTF-8 string specifying the name of this destination.
+ *
+ * @x: [optional] A float specifying the x coordinate of destination
+ *                 position on this page. If not specified the default
+ *                 x coordinate is the left side of the extents of the
+ *                 operations enclosed by the %CAIRO_TAG_DEST begin/end tags. If
+ *                 no operations are enclosed, the x coordidate is 0.
+ *
+ * @y: [optional] A float specifying the y coordinate of destination
+ *                 position on this page. If not specified the default
+ *                 y coordinate is the top of the extents of the
+ *                 operations enclosed by the %CAIRO_TAG_DEST begin/end tags. If
+ *                 no operations are enclosed, the y coordidate is 0.
+ *
+ * @internal: A boolean that if true, the destination name may be
+ *            omitted from PDF where possible. In this case, links
+ *            refer directly to the page and position instead of via
+ *            the named destination table. Note that if this
+ *            destination is referenced by another PDF (see [File Links][file-link]),
+ *            this attribute must be false. Default is false.
+ *
+ * <informalexample><programlisting>
+ * /* Create a hyperlink */
+ * cairo_tag_begin (cr, CAIRO_TAG_LINK, "dest='mydest' internal");
+ * cairo_move_to (cr, 50, 50);
+ * cairo_show_text (cr, "This is a hyperlink.");
+ * cairo_tag_end (cr, CAIRO_TAG_LINK);
+ *
+ * /* Create a destination */
+ * cairo_tag_begin (cr, CAIRO_TAG_DEST, "name='mydest'");
+ * cairo_move_to (cr, 50, 250);
+ * cairo_show_text (cr, "This paragraph is the destination of the above link.");
+ * cairo_tag_end (cr, CAIRO_TAG_DEST);
+ * </programlisting></informalexample>
+ *
+ * # Document Structure (PDF) # {#doc-struct}
+ *
+ * The document structure tags provide a means of specifying structural information
+ * such as headers, paragraphs, tables, and figures. The inclusion of structural information facilitates:
+ * * Extraction of text and graphics for copy and paste
+ * * Reflow of text and graphics in the viewer
+ * * Processing text eg searching and indexing
+ * * Conversion to other formats
+ * * Accessability support
+ *
+ * The list of structure types is specified in section 14.8.4 of the
+ * [PDF Reference](http://www.adobe.com/content/dam/Adobe/en/devnet/acrobat/pdfs/PDF32000_2008.pdf).
+ *
+ * Note the PDF "Link" structure tag is the same as the cairo %CAIRO_TAG_LINK tag.
+ *
+ * The following example creates a document structure for a document containing two section, each with
+ * a header and a paragraph.
+ *
+ * <informalexample><programlisting>
+ * cairo_tag_begin (cr, "Document", NULL);
+ *
+ * cairo_tag_begin (cr, "Sect", NULL);
+ * cairo_tag_begin (cr, "H1", NULL);
+ * cairo_show_text (cr, "Heading 1");
+ * cairo_tag_end (cr, "H1");
+ *
+ * cairo_tag_begin (cr, "P", NULL);
+ * cairo_show_text (cr, "Paragraph 1");
+ * cairo_tag_end (cr, "P");
+ * cairo_tag_end (cr, "Sect");
+ *
+ * cairo_tag_begin (cr, "Sect", NULL);
+ * cairo_tag_begin (cr, "H1", NULL);
+ * cairo_show_text (cr, "Heading 2");
+ * cairo_tag_end (cr, "H1");
+ *
+ * cairo_tag_begin (cr, "P", NULL);
+ * cairo_show_text (cr, "Paragraph 2");
+ * cairo_tag_end (cr, "P");
+ * cairo_tag_end (cr, "Sect");
+ *
+ * cairo_tag_end (cr, "Document");
+ * </programlisting></informalexample>
+ *
+ **/
+
 #define DEFINE_NIL_CONTEXT(status)					\
     {									\
 	CAIRO_REFERENCE_COUNT_INVALID,	/* ref_count */			\
@@ -153,7 +368,11 @@
     DEFINE_NIL_CONTEXT (CAIRO_STATUS_DEVICE_ERROR),
     DEFINE_NIL_CONTEXT (CAIRO_STATUS_INVALID_MESH_CONSTRUCTION),
     DEFINE_NIL_CONTEXT (CAIRO_STATUS_DEVICE_FINISHED),
-    DEFINE_NIL_CONTEXT (CAIRO_STATUS_JBIG2_GLOBAL_MISSING)
+    DEFINE_NIL_CONTEXT (CAIRO_STATUS_JBIG2_GLOBAL_MISSING),
+    DEFINE_NIL_CONTEXT (CAIRO_STATUS_PNG_ERROR),
+    DEFINE_NIL_CONTEXT (CAIRO_STATUS_FREETYPE_ERROR),
+    DEFINE_NIL_CONTEXT (CAIRO_STATUS_WIN32_GDI_ERROR),
+    DEFINE_NIL_CONTEXT (CAIRO_STATUS_TAG_ERROR)
 
 };
 COMPILE_TIME_ASSERT (ARRAY_LENGTH (_cairo_nil) == CAIRO_STATUS_LAST_STATUS - 1);
@@ -260,8 +479,8 @@
  * @cr from being destroyed until a matching call to cairo_destroy()
  * is made.
  *
- * The number of references to a #cairo_t can be get using
- * cairo_get_reference_count().
+ * Use cairo_get_reference_count() to get the number of references to
+ * a #cairo_t.
  *
  * Return value: the referenced #cairo_t.
  *
@@ -625,7 +844,7 @@
 
 
 #if 0
-/**
+/*
  * cairo_set_opacity:
  * @cr: a #cairo_t
  * @opacity: the level of opacity to use when compositing
@@ -635,9 +854,7 @@
  * using the alpha value.
  *
  * The default opacity is 1.
- *
- * Since: TBD
- **/
+ */
 void
 cairo_set_opacity (cairo_t *cr, double opacity)
 {
@@ -2664,6 +2881,100 @@
 }
 
 /**
+ * CAIRO_TAG_DEST:
+ *
+ * Create a destination for a hyperlink. Destination tag attributes
+ * are detailed at [Destinations][dests].
+ *
+ * Since: 1.16
+ **/
+
+/**
+ * CAIRO_TAG_LINK:
+ *
+ * Create hyperlink. Link tag attributes are detailed at
+ * [Links][links].
+ *
+ * Since: 1.16
+ **/
+
+/**
+ * cairo_tag_begin:
+ * @cr: a cairo context
+ * @tag_name: tag name
+ * @attributes: tag attributes
+ *
+ * Marks the beginning of the @tag_name structure. Call
+ * cairo_tag_end() with the same @tag_name to mark the end of the
+ * structure.
+ *
+ * The attributes string is of the form "key1=value2 key2=value2 ...".
+ * Values may be boolean (true/false or 1/0), integer, float, string,
+ * or an array.
+ *
+ * String values are enclosed in single quotes
+ * ('). Single quotes and backslashes inside the string should be
+ * escaped with a backslash.
+ *
+ * Boolean values may be set to true by only
+ * specifying the key. eg the attribute string "key" is the equivalent
+ * to "key=true".
+ *
+ * Arrays are enclosed in '[]'. eg "rect=[1.2 4.3 2.0 3.0]".
+ *
+ * If no attributes are required, @attributes can be an empty string or NULL.
+ *
+ * See [Tags and Links Description][cairo-Tags-and-Links.description]
+ * for the list of tags and attributes.
+ *
+ * Invalid nesting of tags or invalid attributes will cause @cr to
+ * shutdown with a status of %CAIRO_STATUS_TAG_ERROR.
+ *
+ * See cairo_tag_end().
+ *
+ * Since: 1.16
+ **/
+void
+cairo_tag_begin (cairo_t *cr, const char *tag_name, const char *attributes)
+{
+    cairo_status_t status;
+
+    if (unlikely (cr->status))
+	return;
+
+    status = cr->backend->tag_begin (cr, tag_name, attributes);
+    if (unlikely (status))
+	_cairo_set_error (cr, status);
+}
+
+/**
+ * cairo_tag_end:
+ * @cr: a cairo context
+ * @tag_name: tag name
+ *
+ * Marks the end of the @tag_name structure.
+ *
+ * Invalid nesting of tags will cause @cr to shutdown with a status of
+ * %CAIRO_STATUS_TAG_ERROR.
+ *
+ * See cairo_tag_begin().
+ *
+ * Since: 1.16
+ **/
+cairo_public void
+cairo_tag_end (cairo_t *cr, const char *tag_name)
+{
+    cairo_status_t status;
+
+    if (unlikely (cr->status))
+	return;
+
+    status = cr->backend->tag_end (cr, tag_name);
+    if (unlikely (status))
+	_cairo_set_error (cr, status);
+}
+
+/**
  * cairo_select_font_face:
  * @cr: a #cairo_t
  * @family: a font family name, encoded in UTF-8

Modified: trunk/Build/source/libs/cairo/cairo-src/src/cairo.h
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/src/cairo.h	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/src/cairo.h	2018-10-20 03:19:36 UTC (rev 48952)
@@ -292,6 +292,10 @@
  * @CAIRO_STATUS_DEVICE_FINISHED: target device has been finished (Since 1.12)
  * @CAIRO_STATUS_JBIG2_GLOBAL_MISSING: %CAIRO_MIME_TYPE_JBIG2_GLOBAL_ID has been used on at least one image
  *   but no image provided %CAIRO_MIME_TYPE_JBIG2_GLOBAL (Since 1.14)
+ * @CAIRO_STATUS_PNG_ERROR: error occurred in libpng while reading from or writing to a PNG file (Since 1.16)
+ * @CAIRO_STATUS_FREETYPE_ERROR: error occurred in libfreetype (Since 1.16)
+ * @CAIRO_STATUS_WIN32_GDI_ERROR: error occurred in the Windows Graphics Device Interface (Since 1.16)
+ * @CAIRO_STATUS_TAG_ERROR: invalid tag name, attributes, or nesting (Since 1.16)
  * @CAIRO_STATUS_LAST_STATUS: this is a special value indicating the number of
  *   status values defined in this enumeration.  When using this value, note
  *   that the version of cairo at run-time may have additional status values
@@ -348,6 +352,10 @@
     CAIRO_STATUS_INVALID_MESH_CONSTRUCTION,
     CAIRO_STATUS_DEVICE_FINISHED,
     CAIRO_STATUS_JBIG2_GLOBAL_MISSING,
+    CAIRO_STATUS_PNG_ERROR,
+    CAIRO_STATUS_FREETYPE_ERROR,
+    CAIRO_STATUS_WIN32_GDI_ERROR,
+    CAIRO_STATUS_TAG_ERROR,
 
     CAIRO_STATUS_LAST_STATUS
 } cairo_status_t;
@@ -390,7 +398,7 @@
  * @CAIRO_FORMAT_A1: each pixel is a 1-bit quantity holding
  *   an alpha value. Pixels are packed together into 32-bit
  *   quantities. The ordering of the bits matches the
- *   endianess of the platform. On a big-endian machine, the
+ *   endianness of the platform. On a big-endian machine, the
  *   first pixel is in the uppermost bit, on a little-endian
  *   machine the first pixel is in the least-significant bit. (Since 1.0)
  * @CAIRO_FORMAT_RGB16_565: each pixel is a 16-bit quantity
@@ -598,7 +606,7 @@
  * translucent layers too.
  * For a more detailed explanation of the effects of each operator, including
  * the mathematical definitions, see
- * <ulink url="http://cairographics.org/operators/">http://cairographics.org/operators/</ulink>.
+ * <ulink url="https://cairographics.org/operators/">https://cairographics.org/operators/</ulink>.
  *
  * Since: 1.0
  **/
@@ -1018,6 +1026,17 @@
 cairo_public void
 cairo_rectangle_list_destroy (cairo_rectangle_list_t *rectangle_list);
 
+/* Logical structure tagging functions */
+
+#define CAIRO_TAG_DEST "cairo.dest"
+#define CAIRO_TAG_LINK "Link"
+
+cairo_public void
+cairo_tag_begin (cairo_t *cr, const char *tag_name, const char *attributes);
+
+cairo_public void
+cairo_tag_end (cairo_t *cr, const char *tag_name);
+
 /* Font/Text functions */
 
 /**
@@ -1044,7 +1063,7 @@
  *
  * A #cairo_font_face_t specifies all aspects of a font other
  * than the size or font matrix (a font matrix is used to distort
- * a font by sheering it or scaling it unequally in the two
+ * a font by shearing it or scaling it unequally in the two
  * directions) . A font face can be set on a #cairo_t by using
  * cairo_set_font_face(); the size and font matrix are set with
  * cairo_set_font_size() and cairo_set_font_matrix().
@@ -1411,6 +1430,13 @@
 cairo_public cairo_hint_metrics_t
 cairo_font_options_get_hint_metrics (const cairo_font_options_t *options);
 
+cairo_public const char *
+cairo_font_options_get_variations (cairo_font_options_t *options);
+
+cairo_public void
+cairo_font_options_set_variations (cairo_font_options_t *options,
+                                   const char           *variations);
+
 /* This interface is for dealing with text as text, not caring about the
    font object inside the the cairo_t. */
 
@@ -2340,7 +2366,6 @@
  * @CAIRO_SURFACE_TYPE_DRM: The surface is of type Direct Render Manager, since 1.10
  * @CAIRO_SURFACE_TYPE_TEE: The surface is of type 'tee' (a multiplexing surface), since 1.10
  * @CAIRO_SURFACE_TYPE_XML: The surface is of type XML (for debugging), since 1.10
- * @CAIRO_SURFACE_TYPE_SKIA: The surface is of type Skia, since 1.10
  * @CAIRO_SURFACE_TYPE_SUBSURFACE: The surface is a subsurface created with
  *   cairo_surface_create_for_rectangle(), since 1.10
  * @CAIRO_SURFACE_TYPE_COGL: This surface is of type Cogl, since 1.12
@@ -2434,6 +2459,10 @@
 #define CAIRO_MIME_TYPE_JBIG2 "application/x-cairo.jbig2"
 #define CAIRO_MIME_TYPE_JBIG2_GLOBAL "application/x-cairo.jbig2-global"
 #define CAIRO_MIME_TYPE_JBIG2_GLOBAL_ID "application/x-cairo.jbig2-global-id"
+#define CAIRO_MIME_TYPE_CCITT_FAX "image/g3fax"
+#define CAIRO_MIME_TYPE_CCITT_FAX_PARAMS "application/x-cairo.ccitt.params"
+#define CAIRO_MIME_TYPE_EPS "application/postscript"
+#define CAIRO_MIME_TYPE_EPS_PARAMS "application/x-cairo.eps.params"
 
 cairo_public void
 cairo_surface_get_mime_data (cairo_surface_t		*surface,

Modified: trunk/Build/source/libs/cairo/cairo-src/src/cairoint.h
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/src/cairoint.h	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/src/cairoint.h	2018-10-20 03:19:36 UTC (rev 48952)
@@ -107,6 +107,12 @@
 #undef MAX
 #define MAX(a, b) ((a) > (b) ? (a) : (b))
 
+#if _XOPEN_SOURCE >= 600 || defined (_ISOC99_SOURCE)
+#define ISFINITE(x) isfinite (x)
+#else
+#define ISFINITE(x) ((x) * (x) >= 0.) /* check for NaNs */
+#endif
+
 #ifndef FALSE
 #define FALSE 0
 #endif
@@ -282,6 +288,12 @@
     return (c >= '0' && c <= '9');
 }
 
+static inline int cairo_const
+_cairo_isalpha (int c)
+{
+    return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z');
+}
+
 #include "cairo-types-private.h"
 #include "cairo-cache-private.h"
 #include "cairo-reference-count-private.h"
@@ -471,7 +483,8 @@
     CAIRO_SCALED_GLYPH_INFO_METRICS	 = (1 << 0),
     CAIRO_SCALED_GLYPH_INFO_SURFACE	 = (1 << 1),
     CAIRO_SCALED_GLYPH_INFO_PATH	 = (1 << 2),
-    CAIRO_SCALED_GLYPH_INFO_RECORDING_SURFACE = (1 << 3)
+    CAIRO_SCALED_GLYPH_INFO_RECORDING_SURFACE = (1 << 3),
+    CAIRO_SCALED_GLYPH_INFO_COLOR_SURFACE = (1 << 4)
 } cairo_scaled_glyph_info_t;
 
 typedef struct _cairo_scaled_font_subset {
@@ -556,8 +569,12 @@
 		     unsigned long               index,
                      uint32_t                   *ucs4);
 
-    cairo_warn cairo_bool_t
-    (*is_synthetic)(void                       *scaled_font);
+    /* Determine if this scaled font differs from the outlines in the font tables.
+     * eg synthesized bold/italic or a non default variant of a variable font.
+     */
+    cairo_warn cairo_int_status_t
+    (*is_synthetic)(void                       *scaled_font,
+		    cairo_bool_t               *is_synthetic);
 
     /* For type 1 fonts, return the glyph name for a given glyph index.
      * A glyph index and list of glyph names in the Type 1 fonts is provided.
@@ -597,6 +614,9 @@
                            long                  offset,
                            unsigned char        *buffer,
                            unsigned long        *length);
+
+    cairo_bool_t
+    (*has_color_glyphs)   (void                 *scaled_font);
 };
 
 struct _cairo_font_face_backend {
@@ -861,6 +881,9 @@
 			       const cairo_font_options_t	*other);
 
 cairo_private void
+_cairo_font_options_fini (cairo_font_options_t *options);
+
+cairo_private void
 _cairo_font_options_set_lcd_filter (cairo_font_options_t   *options,
 				   cairo_lcd_filter_t  lcd_filter);
 
@@ -892,6 +915,9 @@
 			       int			    num_clusters,
 			       cairo_text_cluster_flags_t   cluster_flags);
 
+cairo_private unsigned long
+_cairo_string_hash (const char *str, int len);
+
 cairo_private cairo_status_t
 _cairo_intern_string (const char **str_inout, int len);
 
@@ -899,8 +925,11 @@
 _cairo_intern_string_reset_static_data (void);
 
 cairo_private const char *
-cairo_get_locale_decimal_point (void);
+_cairo_get_locale_decimal_point (void);
 
+cairo_private double
+_cairo_strtod (const char *nptr, char **endptr);
+
 /* cairo-path-fixed.c */
 cairo_private cairo_path_fixed_t *
 _cairo_path_fixed_create (void);
@@ -1021,6 +1050,7 @@
 _cairo_path_fixed_approximate_stroke_extents (const cairo_path_fixed_t *path,
 					      const cairo_stroke_style_t *style,
 					      const cairo_matrix_t *ctm,
+					      cairo_bool_t vector,
 					      cairo_rectangle_int_t *extents);
 
 cairo_private cairo_status_t
@@ -1244,6 +1274,11 @@
                                            cairo_scaled_font_t *scaled_font,
                                            cairo_surface_t *recording_surface);
 
+cairo_private void
+_cairo_scaled_glyph_set_color_surface (cairo_scaled_glyph_t *scaled_glyph,
+		                       cairo_scaled_font_t *scaled_font,
+		                       cairo_image_surface_t *surface);
+
 cairo_private cairo_int_status_t
 _cairo_scaled_glyph_lookup (cairo_scaled_font_t *scaled_font,
 			    unsigned long index,
@@ -1307,6 +1342,9 @@
 
 /* cairo-surface.c */
 
+cairo_private cairo_bool_t
+_cairo_surface_has_mime_image (cairo_surface_t *surface);
+
 cairo_private cairo_status_t
 _cairo_surface_copy_mime_data (cairo_surface_t *dst,
 			       cairo_surface_t *src);
@@ -1335,7 +1373,8 @@
 _cairo_surface_init (cairo_surface_t			*surface,
 		     const cairo_surface_backend_t	*backend,
 		     cairo_device_t			*device,
-		     cairo_content_t			 content);
+		     cairo_content_t			 content,
+		     cairo_bool_t                        is_vector);
 
 cairo_private void
 _cairo_surface_set_font_options (cairo_surface_t       *surface,
@@ -1416,6 +1455,17 @@
 				 const cairo_clip_t		    *clip);
 
 cairo_private cairo_status_t
+_cairo_surface_tag (cairo_surface_t	        *surface,
+		    cairo_bool_t                 begin,
+		    const char                  *tag_name,
+		    const char                  *attributes,
+		    const cairo_pattern_t	*source,
+		    const cairo_stroke_style_t	*stroke_style,
+		    const cairo_matrix_t	*ctm,
+		    const cairo_matrix_t	*ctm_inverse,
+		    const cairo_clip_t	        *clip);
+
+cairo_private cairo_status_t
 _cairo_surface_acquire_source_image (cairo_surface_t         *surface,
 				     cairo_image_surface_t  **image_out,
 				     void                   **image_extra);
@@ -1468,7 +1518,7 @@
  * for that, even without being considered "valid" for the sake of
  * things like cairo_image_surface_create().
  *
- * Since 1.2.0 we ran into the same situtation with X servers with BGR
+ * Since 1.2.0 we ran into the same situation with X servers with BGR
  * visuals. This time we invented #cairo_internal_format_t instead,
  * (see it for more discussion).
  *
@@ -1536,6 +1586,9 @@
 cairo_private void
 _cairo_image_reset_static_data (void);
 
+cairo_private void
+_cairo_image_compositor_reset_static_data (void);
+
 cairo_private cairo_surface_t *
 _cairo_image_surface_create_with_pixman_format (unsigned char		*data,
 						pixman_format_code_t	 pixman_format,
@@ -1779,6 +1832,12 @@
 				       int                      *out_x_offset,
 				       int                      *out_y_offset);
 
+cairo_private void
+_cairo_debug_print_matrix (FILE *file, const cairo_matrix_t *matrix);
+
+cairo_private void
+_cairo_debug_print_rect (FILE *file, const cairo_rectangle_int_t *rect);
+
 cairo_private cairo_status_t
 _cairo_bentley_ottmann_tessellate_rectilinear_polygon (cairo_traps_t	 *traps,
 						       const cairo_polygon_t *polygon,
@@ -1847,6 +1906,10 @@
 _cairo_ucs4_to_utf8 (uint32_t    unicode,
 		     char       *utf8);
 
+cairo_private int
+_cairo_ucs4_to_utf16 (uint32_t    unicode,
+		      uint16_t   *utf16);
+
 #if CAIRO_HAS_WIN32_FONT || CAIRO_HAS_QUARTZ_FONT || CAIRO_HAS_PDF_OPERATORS
 # define CAIRO_HAS_UTF8_TO_UTF16 1
 #endif
@@ -1868,6 +1931,10 @@
 cairo_private void
 _cairo_observers_notify (cairo_list_t *observers, void *arg);
 
+/* Open a file with a UTF-8 filename */
+cairo_private cairo_status_t
+_cairo_fopen (const char *filename, const char *mode, FILE **file_out);
+
 /* Avoid unnecessary PLT entries.  */
 slim_hidden_proto (cairo_clip_preserve);
 slim_hidden_proto (cairo_close_path);
@@ -2060,7 +2127,7 @@
 #endif
 
 cairo_private void
-_cairo_debug_print_path (FILE *stream, cairo_path_fixed_t *path);
+_cairo_debug_print_path (FILE *stream, const cairo_path_fixed_t *path);
 
 cairo_private void
 _cairo_debug_print_polygon (FILE *stream, cairo_polygon_t *polygon);

Modified: trunk/Build/source/libs/cairo/cairo-src/src/test-compositor-surface.c
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/src/test-compositor-surface.c	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/src/test-compositor-surface.c	2018-10-20 03:19:36 UTC (rev 48952)
@@ -78,7 +78,7 @@
     if (unlikely (pixman_image == NULL))
 	return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
 
-    surface = malloc (sizeof (test_compositor_surface_t));
+    surface = _cairo_malloc (sizeof (test_compositor_surface_t));
     if (unlikely (surface == NULL)) {
 	pixman_image_unref (pixman_image);
 	return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
@@ -87,7 +87,8 @@
     _cairo_surface_init (&surface->base.base,
 			 &test_compositor_surface_backend,
 			 NULL, /* device */
-			 content);
+			 content,
+			 FALSE); /* is_vector */
     _cairo_image_surface_init (&surface->base, pixman_image, pixman_format);
 
     surface->base.compositor = compositor;

Modified: trunk/Build/source/libs/cairo/cairo-src/src/test-null-compositor-surface.c
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/src/test-null-compositor-surface.c	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/src/test-null-compositor-surface.c	2018-10-20 03:19:36 UTC (rev 48952)
@@ -81,7 +81,7 @@
     if (unlikely (pixman_image == NULL))
 	return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
 
-    surface = malloc (sizeof (test_compositor_surface_t));
+    surface = _cairo_malloc (sizeof (test_compositor_surface_t));
     if (unlikely (surface == NULL)) {
 	pixman_image_unref (pixman_image);
 	return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
@@ -90,7 +90,8 @@
     _cairo_surface_init (&surface->base.base,
 			 &test_compositor_surface_backend,
 			 NULL, /* device */
-			 content);
+			 content,
+			 FALSE); /* is_vector */
     _cairo_image_surface_init (&surface->base, pixman_image, pixman_format);
 
     surface->base.compositor = compositor;
@@ -403,9 +404,10 @@
 static const cairo_compositor_t *
 no_traps_compositor_get (void)
 {
+    static cairo_atomic_once_t once = CAIRO_ATOMIC_ONCE_INIT;
     static cairo_traps_compositor_t compositor;
 
-    if (compositor.base.delegate == NULL) {
+    if (_cairo_atomic_init_once_enter(&once)) {
 	_cairo_traps_compositor_init (&compositor,
 				      no_fallback_compositor_get ());
 
@@ -425,6 +427,8 @@
 	compositor.composite_traps = composite_traps;
 	compositor.check_composite_glyphs = check_composite_glyphs;
 	compositor.composite_glyphs = composite_glyphs;
+
+	_cairo_atomic_init_once_leave(&once);
     }
 
     return &compositor.base;
@@ -433,9 +437,10 @@
 static const cairo_compositor_t *
 no_spans_compositor_get (void)
 {
+    static cairo_atomic_once_t once = CAIRO_ATOMIC_ONCE_INIT;
     static cairo_spans_compositor_t compositor;
 
-    if (compositor.base.delegate == NULL) {
+    if (_cairo_atomic_init_once_enter(&once)) {
 	_cairo_spans_compositor_init (&compositor,
 				      no_traps_compositor_get());
 
@@ -447,6 +452,8 @@
 	//compositor.check_span_renderer = check_span_renderer;
 	compositor.renderer_init = span_renderer_init;
 	compositor.renderer_fini = span_renderer_fini;
+
+	_cairo_atomic_init_once_leave(&once);
     }
 
     return &compositor.base;

Modified: trunk/Build/source/libs/cairo/cairo-src/src/test-paginated-surface.c
===================================================================
--- trunk/Build/source/libs/cairo/cairo-src/src/test-paginated-surface.c	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/cairo-src/src/test-paginated-surface.c	2018-10-20 03:19:36 UTC (rev 48952)
@@ -74,7 +74,7 @@
     if (unlikely (status))
 	return _cairo_surface_create_in_error (status);
 
-    surface = malloc (sizeof (test_paginated_surface_t));
+    surface = _cairo_malloc (sizeof (test_paginated_surface_t));
     if (unlikely (surface == NULL))
 	return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
 
@@ -81,7 +81,8 @@
     _cairo_surface_init (&surface->base,
 			 &test_paginated_surface_backend,
 			 NULL, /* device */
-			 target->content);
+			 target->content,
+			 TRUE); /* is_vector */
 
     surface->target = cairo_surface_reference (target);
 
@@ -231,7 +232,7 @@
 }
 
 
-static void
+static cairo_int_status_t
 _test_paginated_surface_set_paginated_mode (void			*abstract_surface,
 					    cairo_paginated_mode_t	 mode)
 {
@@ -238,6 +239,8 @@
     test_paginated_surface_t *surface = abstract_surface;
 
     surface->paginated_mode = mode;
+
+    return CAIRO_STATUS_SUCCESS;
 }
 
 static const cairo_surface_backend_t test_paginated_surface_backend = {

Modified: trunk/Build/source/libs/cairo/configure
===================================================================
--- trunk/Build/source/libs/cairo/configure	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/configure	2018-10-20 03:19:36 UTC (rev 48952)
@@ -1,6 +1,6 @@
 #! /bin/sh
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for cairo (TeX Live) 1.14.12.
+# Generated by GNU Autoconf 2.69 for cairo (TeX Live) 1.16.0.
 #
 # Report bugs to <tex-k at tug.org>.
 #
@@ -580,8 +580,8 @@
 # Identity of this package.
 PACKAGE_NAME='cairo (TeX Live)'
 PACKAGE_TARNAME='cairo--tex-live-'
-PACKAGE_VERSION='1.14.12'
-PACKAGE_STRING='cairo (TeX Live) 1.14.12'
+PACKAGE_VERSION='1.16.0'
+PACKAGE_STRING='cairo (TeX Live) 1.16.0'
 PACKAGE_BUGREPORT='tex-k at tug.org'
 PACKAGE_URL=''
 
@@ -1349,7 +1349,7 @@
   # Omit some internal or obsolete options to make the list less imposing.
   # This message is too long to be a string in the A/UX 3.1 sh.
   cat <<_ACEOF
-\`configure' configures cairo (TeX Live) 1.14.12 to adapt to many kinds of systems.
+\`configure' configures cairo (TeX Live) 1.16.0 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1420,7 +1420,7 @@
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of cairo (TeX Live) 1.14.12:";;
+     short | recursive ) echo "Configuration of cairo (TeX Live) 1.16.0:";;
    esac
   cat <<\_ACEOF
 
@@ -1523,7 +1523,7 @@
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-cairo (TeX Live) configure 1.14.12
+cairo (TeX Live) configure 1.16.0
 generated by GNU Autoconf 2.69
 
 Copyright (C) 2012 Free Software Foundation, Inc.
@@ -2129,7 +2129,7 @@
 This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
 
-It was created by cairo (TeX Live) $as_me 1.14.12, which was
+It was created by cairo (TeX Live) $as_me 1.16.0, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   $ $0 $@
@@ -4383,7 +4383,7 @@
 
 # Define the identity of the package.
  PACKAGE='cairo--tex-live-'
- VERSION='1.14.12'
+ VERSION='1.16.0'
 
 
 cat >>confdefs.h <<_ACEOF
@@ -7274,7 +7274,7 @@
 # report actual input values of CONFIG_FILES etc. instead of their
 # values after options handling.
 ac_log="
-This file was extended by cairo (TeX Live) $as_me 1.14.12, which was
+This file was extended by cairo (TeX Live) $as_me 1.16.0, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -7340,7 +7340,7 @@
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
 ac_cs_version="\\
-cairo (TeX Live) config.status 1.14.12
+cairo (TeX Live) config.status 1.16.0
 configured by $0, generated by GNU Autoconf 2.69,
   with options \\"\$ac_cs_config\\"
 

Modified: trunk/Build/source/libs/cairo/version.ac
===================================================================
--- trunk/Build/source/libs/cairo/version.ac	2018-10-20 00:23:14 UTC (rev 48951)
+++ trunk/Build/source/libs/cairo/version.ac	2018-10-20 03:19:36 UTC (rev 48952)
@@ -8,4 +8,4 @@
 dnl --------------------------------------------------------
 dnl
 dnl  m4-include this file to define the current cairo version
-m4_define([cairo_version], [1.14.12])
+m4_define([cairo_version], [1.16.0])



More information about the tex-live-commits mailing list