summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Build/source/libs/README2
-rw-r--r--Build/source/libs/cairo/ChangeLog5
-rw-r--r--Build/source/libs/cairo/Makefile.am3
-rw-r--r--Build/source/libs/cairo/Makefile.in38
-rw-r--r--Build/source/libs/cairo/README4
-rw-r--r--Build/source/libs/cairo/TLpatches/ChangeLog4
-rw-r--r--Build/source/libs/cairo/TLpatches/TL-Changes5
-rw-r--r--Build/source/libs/cairo/cairo-src/BUGS8
-rw-r--r--Build/source/libs/cairo/cairo-src/HACKING12
-rw-r--r--Build/source/libs/cairo/cairo-src/INSTALL4
-rw-r--r--Build/source/libs/cairo/cairo-src/NEWS791
-rw-r--r--Build/source/libs/cairo/cairo-src/README32
-rw-r--r--Build/source/libs/cairo/cairo-src/RELEASING68
-rw-r--r--Build/source/libs/cairo/cairo-src/build/Makefile.am.gtk-doc27
-rw-r--r--Build/source/libs/cairo/cairo-src/build/Makefile.am.releasing2
-rw-r--r--Build/source/libs/cairo/cairo-src/build/Makefile.win32.features2
-rw-r--r--Build/source/libs/cairo/cairo-src/build/Makefile.win32.features-h6
-rw-r--r--Build/source/libs/cairo/cairo-src/build/aclocal.cairo.m410
-rw-r--r--Build/source/libs/cairo/cairo-src/build/aclocal.float.m42
-rw-r--r--Build/source/libs/cairo/cairo-src/build/aclocal.pkg.m42
-rw-r--r--Build/source/libs/cairo/cairo-src/build/configure.ac.features3
-rw-r--r--Build/source/libs/cairo/cairo-src/build/configure.ac.system2
-rw-r--r--Build/source/libs/cairo/cairo-src/build/configure.ac.tools2
-rw-r--r--Build/source/libs/cairo/cairo-src/build/gtk-doc.m427
-rw-r--r--Build/source/libs/cairo/cairo-src/cairo-version.h4
-rw-r--r--Build/source/libs/cairo/cairo-src/config.h.in35
-rw-r--r--Build/source/libs/cairo/cairo-src/configure.ac86
-rw-r--r--Build/source/libs/cairo/cairo-src/src/Makefile.am.features32
-rw-r--r--Build/source/libs/cairo/cairo-src/src/Makefile.sources86
-rw-r--r--Build/source/libs/cairo/cairo-src/src/Makefile.win32.features32
-rw-r--r--Build/source/libs/cairo/cairo-src/src/cairo-analysis-surface.c282
-rw-r--r--Build/source/libs/cairo/cairo-src/src/cairo-atomic-private.h74
-rw-r--r--Build/source/libs/cairo/cairo-src/src/cairo-atomic.c14
-rw-r--r--Build/source/libs/cairo/cairo-src/src/cairo-backend-private.h3
-rw-r--r--Build/source/libs/cairo/cairo-src/src/cairo-base64-stream.c2
-rw-r--r--Build/source/libs/cairo/cairo-src/src/cairo-base85-stream.c2
-rw-r--r--Build/source/libs/cairo/cairo-src/src/cairo-bentley-ottmann-rectangular.c27
-rw-r--r--Build/source/libs/cairo/cairo-src/src/cairo-bentley-ottmann.c12
-rw-r--r--Build/source/libs/cairo/cairo-src/src/cairo-botor-scan-converter.c40
-rw-r--r--Build/source/libs/cairo/cairo-src/src/cairo-box-inline.h10
-rw-r--r--Build/source/libs/cairo/cairo-src/src/cairo-boxes-private.h3
-rw-r--r--Build/source/libs/cairo/cairo-src/src/cairo-boxes.c34
-rw-r--r--Build/source/libs/cairo/cairo-src/src/cairo-cff-subset.c76
-rw-r--r--Build/source/libs/cairo/cairo-src/src/cairo-clip-boxes.c60
-rw-r--r--Build/source/libs/cairo/cairo-src/src/cairo-clip-tor-scan-converter.c4
-rw-r--r--Build/source/libs/cairo/cairo-src/src/cairo-clip.c8
-rw-r--r--Build/source/libs/cairo/cairo-src/src/cairo-cogl-context.c2
-rw-r--r--Build/source/libs/cairo/cairo-src/src/cairo-cogl-gradient.c4
-rw-r--r--Build/source/libs/cairo/cairo-src/src/cairo-cogl-surface.c11
-rw-r--r--Build/source/libs/cairo/cairo-src/src/cairo-compiler-private.h2
-rw-r--r--Build/source/libs/cairo/cairo-src/src/cairo-composite-rectangles.c15
-rw-r--r--Build/source/libs/cairo/cairo-src/src/cairo-damage.c6
-rw-r--r--Build/source/libs/cairo/cairo-src/src/cairo-debug.c21
-rw-r--r--Build/source/libs/cairo/cairo-src/src/cairo-default-context.c23
-rw-r--r--Build/source/libs/cairo/cairo-src/src/cairo-deflate-stream.c2
-rw-r--r--Build/source/libs/cairo/cairo-src/src/cairo-device.c8
-rw-r--r--Build/source/libs/cairo/cairo-src/src/cairo-directfb-surface.c3
-rw-r--r--Build/source/libs/cairo/cairo-src/src/cairo-error-private.h4
-rw-r--r--Build/source/libs/cairo/cairo-src/src/cairo-font-face-twin.c4
-rw-r--r--Build/source/libs/cairo/cairo-src/src/cairo-font-face.c4
-rw-r--r--Build/source/libs/cairo/cairo-src/src/cairo-font-options.c97
-rw-r--r--Build/source/libs/cairo/cairo-src/src/cairo-freed-pool-private.h10
-rw-r--r--Build/source/libs/cairo/cairo-src/src/cairo-freed-pool.c10
-rw-r--r--Build/source/libs/cairo/cairo-src/src/cairo-freelist-private.h2
-rw-r--r--Build/source/libs/cairo/cairo-src/src/cairo-freelist.c12
-rw-r--r--Build/source/libs/cairo/cairo-src/src/cairo-ft-font.c381
-rw-r--r--Build/source/libs/cairo/cairo-src/src/cairo-gl-composite.c281
-rw-r--r--Build/source/libs/cairo/cairo-src/src/cairo-gl-device.c145
-rw-r--r--Build/source/libs/cairo/cairo-src/src/cairo-gl-dispatch.c20
-rw-r--r--Build/source/libs/cairo/cairo-src/src/cairo-gl-glyphs.c46
-rw-r--r--Build/source/libs/cairo/cairo-src/src/cairo-gl-gradient-private.h9
-rw-r--r--Build/source/libs/cairo/cairo-src/src/cairo-gl-gradient.c49
-rw-r--r--Build/source/libs/cairo/cairo-src/src/cairo-gl-info.c8
-rw-r--r--Build/source/libs/cairo/cairo-src/src/cairo-gl-msaa-compositor.c40
-rw-r--r--Build/source/libs/cairo/cairo-src/src/cairo-gl-operand.c113
-rw-r--r--Build/source/libs/cairo/cairo-src/src/cairo-gl-private.h26
-rw-r--r--Build/source/libs/cairo/cairo-src/src/cairo-gl-shaders.c185
-rw-r--r--Build/source/libs/cairo/cairo-src/src/cairo-gl-source.c10
-rw-r--r--Build/source/libs/cairo/cairo-src/src/cairo-gl-spans-compositor.c59
-rw-r--r--Build/source/libs/cairo/cairo-src/src/cairo-gl-surface.c273
-rw-r--r--Build/source/libs/cairo/cairo-src/src/cairo-gl-traps-compositor.c55
-rw-r--r--Build/source/libs/cairo/cairo-src/src/cairo-gl.h2
-rw-r--r--Build/source/libs/cairo/cairo-src/src/cairo-glx-context.c2
-rw-r--r--Build/source/libs/cairo/cairo-src/src/cairo-gstate-private.h9
-rw-r--r--Build/source/libs/cairo/cairo-src/src/cairo-gstate.c72
-rw-r--r--Build/source/libs/cairo/cairo-src/src/cairo-hash.c2
-rw-r--r--Build/source/libs/cairo/cairo-src/src/cairo-image-compositor.c70
-rw-r--r--Build/source/libs/cairo/cairo-src/src/cairo-image-source.c82
-rw-r--r--Build/source/libs/cairo/cairo-src/src/cairo-image-surface-private.h3
-rw-r--r--Build/source/libs/cairo/cairo-src/src/cairo-image-surface.c95
-rw-r--r--Build/source/libs/cairo/cairo-src/src/cairo-line.c8
-rw-r--r--Build/source/libs/cairo/cairo-src/src/cairo-lzw.c2
-rw-r--r--Build/source/libs/cairo/cairo-src/src/cairo-malloc-private.h2
-rw-r--r--Build/source/libs/cairo/cairo-src/src/cairo-matrix.c6
-rw-r--r--Build/source/libs/cairo/cairo-src/src/cairo-mempool.c2
-rw-r--r--Build/source/libs/cairo/cairo-src/src/cairo-mesh-pattern-rasterizer.c2
-rw-r--r--Build/source/libs/cairo/cairo-src/src/cairo-misc.c179
-rw-r--r--Build/source/libs/cairo/cairo-src/src/cairo-mono-scan-converter.c2
-rw-r--r--Build/source/libs/cairo/cairo-src/src/cairo-os2-surface.c7
-rw-r--r--Build/source/libs/cairo/cairo-src/src/cairo-output-stream.c25
-rw-r--r--Build/source/libs/cairo/cairo-src/src/cairo-paginated-private.h20
-rw-r--r--Build/source/libs/cairo/cairo-src/src/cairo-paginated-surface.c113
-rw-r--r--Build/source/libs/cairo/cairo-src/src/cairo-path-bounds.c23
-rw-r--r--Build/source/libs/cairo/cairo-src/src/cairo-path-fixed.c4
-rw-r--r--Build/source/libs/cairo/cairo-src/src/cairo-path.c4
-rw-r--r--Build/source/libs/cairo/cairo-src/src/cairo-pattern-private.h8
-rw-r--r--Build/source/libs/cairo/cairo-src/src/cairo-pattern.c140
-rw-r--r--Build/source/libs/cairo/cairo-src/src/cairo-pdf-interchange.c1728
-rw-r--r--Build/source/libs/cairo/cairo-src/src/cairo-pdf-operators-private.h8
-rw-r--r--Build/source/libs/cairo/cairo-src/src/cairo-pdf-operators.c44
-rw-r--r--Build/source/libs/cairo/cairo-src/src/cairo-pdf-shading.c2
-rw-r--r--Build/source/libs/cairo/cairo-src/src/cairo-pdf-surface-private.h185
-rw-r--r--Build/source/libs/cairo/cairo-src/src/cairo-pdf-surface.c1621
-rw-r--r--Build/source/libs/cairo/cairo-src/src/cairo-pdf.h67
-rw-r--r--Build/source/libs/cairo/cairo-src/src/cairo-pen.c2
-rw-r--r--Build/source/libs/cairo/cairo-src/src/cairo-png.c55
-rw-r--r--Build/source/libs/cairo/cairo-src/src/cairo-polygon-intersect.c7
-rw-r--r--Build/source/libs/cairo/cairo-src/src/cairo-polygon-reduce.c2
-rw-r--r--Build/source/libs/cairo/cairo-src/src/cairo-polygon.c2
-rw-r--r--Build/source/libs/cairo/cairo-src/src/cairo-ps-surface-private.h27
-rw-r--r--Build/source/libs/cairo/cairo-src/src/cairo-ps-surface.c1940
-rw-r--r--Build/source/libs/cairo/cairo-src/src/cairo-qt-surface.cpp10
-rw-r--r--Build/source/libs/cairo/cairo-src/src/cairo-quartz-font.c57
-rw-r--r--Build/source/libs/cairo/cairo-src/src/cairo-quartz-image-surface.c5
-rw-r--r--Build/source/libs/cairo/cairo-src/src/cairo-quartz-image.h2
-rw-r--r--Build/source/libs/cairo/cairo-src/src/cairo-quartz-private.h12
-rw-r--r--Build/source/libs/cairo/cairo-src/src/cairo-quartz-surface.c26
-rw-r--r--Build/source/libs/cairo/cairo-src/src/cairo-quartz.h2
-rw-r--r--Build/source/libs/cairo/cairo-src/src/cairo-recording-surface-private.h19
-rw-r--r--Build/source/libs/cairo/cairo-src/src/cairo-recording-surface.c267
-rw-r--r--Build/source/libs/cairo/cairo-src/src/cairo-region.c6
-rw-r--r--Build/source/libs/cairo/cairo-src/src/cairo-scaled-font-private.h3
-rw-r--r--Build/source/libs/cairo/cairo-src/src/cairo-scaled-font-subsets.c14
-rw-r--r--Build/source/libs/cairo/cairo-src/src/cairo-scaled-font.c59
-rw-r--r--Build/source/libs/cairo/cairo-src/src/cairo-script-surface.c26
-rw-r--r--Build/source/libs/cairo/cairo-src/src/cairo-skia.h66
-rw-r--r--Build/source/libs/cairo/cairo-src/src/cairo-spans-private.h4
-rw-r--r--Build/source/libs/cairo/cairo-src/src/cairo-spans.c8
-rw-r--r--Build/source/libs/cairo/cairo-src/src/cairo-stroke-style.c2
-rw-r--r--Build/source/libs/cairo/cairo-src/src/cairo-surface-backend-private.h12
-rw-r--r--Build/source/libs/cairo/cairo-src/src/cairo-surface-observer.c9
-rw-r--r--Build/source/libs/cairo/cairo-src/src/cairo-surface-private.h1
-rw-r--r--Build/source/libs/cairo/cairo-src/src/cairo-surface-snapshot.c12
-rw-r--r--Build/source/libs/cairo/cairo-src/src/cairo-surface-subsurface.c10
-rw-r--r--Build/source/libs/cairo/cairo-src/src/cairo-surface-wrapper-private.h12
-rw-r--r--Build/source/libs/cairo/cairo-src/src/cairo-surface-wrapper.c66
-rw-r--r--Build/source/libs/cairo/cairo-src/src/cairo-surface.c353
-rw-r--r--Build/source/libs/cairo/cairo-src/src/cairo-svg-surface-private.h9
-rw-r--r--Build/source/libs/cairo/cairo-src/src/cairo-svg-surface.c316
-rw-r--r--Build/source/libs/cairo/cairo-src/src/cairo-svg.h47
-rw-r--r--Build/source/libs/cairo/cairo-src/src/cairo-tag-attributes-private.h99
-rw-r--r--Build/source/libs/cairo/cairo-src/src/cairo-tag-attributes.c702
-rw-r--r--Build/source/libs/cairo/cairo-src/src/cairo-tag-stack-private.h107
-rw-r--r--Build/source/libs/cairo/cairo-src/src/cairo-tag-stack.c280
-rw-r--r--Build/source/libs/cairo/cairo-src/src/cairo-tee-surface.c5
-rw-r--r--Build/source/libs/cairo/cairo-src/src/cairo-tor-scan-converter.c6
-rw-r--r--Build/source/libs/cairo/cairo-src/src/cairo-tor22-scan-converter.c6
-rw-r--r--Build/source/libs/cairo/cairo-src/src/cairo-toy-font-face.c2
-rw-r--r--Build/source/libs/cairo/cairo-src/src/cairo-traps.c2
-rw-r--r--Build/source/libs/cairo/cairo-src/src/cairo-tristrip.c2
-rw-r--r--Build/source/libs/cairo/cairo-src/src/cairo-truetype-subset.c88
-rw-r--r--Build/source/libs/cairo/cairo-src/src/cairo-type1-fallback.c2
-rw-r--r--Build/source/libs/cairo/cairo-src/src/cairo-type1-subset.c34
-rw-r--r--Build/source/libs/cairo/cairo-src/src/cairo-type3-glyph-surface.c28
-rw-r--r--Build/source/libs/cairo/cairo-src/src/cairo-types-private.h1
-rw-r--r--Build/source/libs/cairo/cairo-src/src/cairo-unicode.c37
-rw-r--r--Build/source/libs/cairo/cairo-src/src/cairo-user-font.c4
-rw-r--r--Build/source/libs/cairo/cairo-src/src/cairo-version.c4
-rw-r--r--Build/source/libs/cairo/cairo-src/src/cairo-vg-surface.c9
-rw-r--r--Build/source/libs/cairo/cairo-src/src/cairo-vg.h4
-rw-r--r--Build/source/libs/cairo/cairo-src/src/cairo-win32.h4
-rw-r--r--Build/source/libs/cairo/cairo-src/src/cairo-xcb-connection.c6
-rw-r--r--Build/source/libs/cairo/cairo-src/src/cairo-xcb-screen.c2
-rw-r--r--Build/source/libs/cairo/cairo-src/src/cairo-xcb-shm.c2
-rw-r--r--Build/source/libs/cairo/cairo-src/src/cairo-xcb-surface-core.c10
-rw-r--r--Build/source/libs/cairo/cairo-src/src/cairo-xcb-surface-render.c17
-rw-r--r--Build/source/libs/cairo/cairo-src/src/cairo-xcb-surface.c5
-rw-r--r--Build/source/libs/cairo/cairo-src/src/cairo-xlib-core-compositor.c5
-rw-r--r--Build/source/libs/cairo/cairo-src/src/cairo-xlib-display.c2
-rw-r--r--Build/source/libs/cairo/cairo-src/src/cairo-xlib-private.h2
-rw-r--r--Build/source/libs/cairo/cairo-src/src/cairo-xlib-render-compositor.c25
-rw-r--r--Build/source/libs/cairo/cairo-src/src/cairo-xlib-screen.c2
-rw-r--r--Build/source/libs/cairo/cairo-src/src/cairo-xlib-source.c13
-rw-r--r--Build/source/libs/cairo/cairo-src/src/cairo-xlib-surface-shm.c11
-rw-r--r--Build/source/libs/cairo/cairo-src/src/cairo-xlib-surface.c13
-rw-r--r--Build/source/libs/cairo/cairo-src/src/cairo-xlib-visual.c2
-rw-r--r--Build/source/libs/cairo/cairo-src/src/cairo-xlib-xcb-surface.c7
-rw-r--r--Build/source/libs/cairo/cairo-src/src/cairo-xml-surface.c11
-rw-r--r--Build/source/libs/cairo/cairo-src/src/cairo.c325
-rw-r--r--Build/source/libs/cairo/cairo-src/src/cairo.h37
-rw-r--r--Build/source/libs/cairo/cairo-src/src/cairoint.h81
-rw-r--r--Build/source/libs/cairo/cairo-src/src/test-compositor-surface.c5
-rw-r--r--Build/source/libs/cairo/cairo-src/src/test-null-compositor-surface.c15
-rw-r--r--Build/source/libs/cairo/cairo-src/src/test-paginated-surface.c9
-rwxr-xr-xBuild/source/libs/cairo/configure20
-rw-r--r--Build/source/libs/cairo/version.ac2
196 files changed, 11015 insertions, 2976 deletions
diff --git a/Build/source/libs/README b/Build/source/libs/README
index 60bbe4980cd..850fa0b8e53 100644
--- a/Build/source/libs/README
+++ b/Build/source/libs/README
@@ -9,7 +9,7 @@ bypassing or using the original one.
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
diff --git a/Build/source/libs/cairo/ChangeLog b/Build/source/libs/cairo/ChangeLog
index fce379febab..b7751e92f12 100644
--- a/Build/source/libs/cairo/ChangeLog
+++ b/Build/source/libs/cairo/ChangeLog
@@ -1,3 +1,8 @@
+2018-10-20 Akira Kakuto <kakuto@fuk.kindai.ac.jp>
+
+ Import cairo-1.16.0.
+ * Makefile.am, version.ac: Adapted.
+
2017-12-07 Akira Kakuto <kakuto@fuk.kindai.ac.jp>
Import cairo-1.14.12.
diff --git a/Build/source/libs/cairo/Makefile.am b/Build/source/libs/cairo/Makefile.am
index dfa3fa02035..0d7134e6267 100644
--- a/Build/source/libs/cairo/Makefile.am
+++ b/Build/source/libs/cairo/Makefile.am
@@ -98,6 +98,7 @@ libcairo_a_SOURCES = \
@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 @@ libcairo_a_SOURCES = \
@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 \
diff --git a/Build/source/libs/cairo/Makefile.in b/Build/source/libs/cairo/Makefile.in
index 7bb60847fbc..31347968c86 100644
--- a/Build/source/libs/cairo/Makefile.in
+++ b/Build/source/libs/cairo/Makefile.in
@@ -234,8 +234,9 @@ am__libcairo_a_SOURCES_DIST = \
@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 @@ am__libcairo_a_SOURCES_DIST = \
@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 @@ am_libcairo_a_OBJECTS = \
@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 @@ am_libcairo_a_OBJECTS = \
@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 @@ am__depfiles_remade = ./$(DEPDIR)/cairotst-cairotst.Po \
@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 @@ am__depfiles_remade = ./$(DEPDIR)/cairotst-cairotst.Po \
@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 @@ libcairo_a_SOURCES = @CAIRO_TREE@/src/cairo-analysis-surface.c \
@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 @@ libcairo_a_SOURCES = @CAIRO_TREE@/src/cairo-analysis-surface.c \
@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 @@ clean-noinstLIBRARIES:
@CAIRO_TREE@/src/cairo-pattern.$(OBJEXT): \
@CAIRO_TREE@/src/$(am__dirstamp) \
@CAIRO_TREE@/src/$(DEPDIR)/$(am__dirstamp)
+@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 @@ clean-noinstLIBRARIES:
@CAIRO_TREE@/src/cairo-surface-wrapper.$(OBJEXT): \
@CAIRO_TREE@/src/$(am__dirstamp) \
@CAIRO_TREE@/src/$(DEPDIR)/$(am__dirstamp)
+@CAIRO_TREE@/src/cairo-tag-attributes.$(OBJEXT): \
+ @CAIRO_TREE@/src/$(am__dirstamp) \
+ @CAIRO_TREE@/src/$(DEPDIR)/$(am__dirstamp)
+@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 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@@CAIRO_TREE@/src/$(DEPDIR)/cairo-path-stroke.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@@CAIRO_TREE@/src/$(DEPDIR)/cairo-path.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@@CAIRO_TREE@/src/$(DEPDIR)/cairo-pattern.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@@CAIRO_TREE@/src/$(DEPDIR)/cairo-pdf-interchange.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@@CAIRO_TREE@/src/$(DEPDIR)/cairo-pen.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@@CAIRO_TREE@/src/$(DEPDIR)/cairo-png.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@@CAIRO_TREE@/src/$(DEPDIR)/cairo-polygon-intersect.Po@am__quote@ # am--include-marker
@@ -1821,6 +1843,8 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@@CAIRO_TREE@/src/$(DEPDIR)/cairo-surface-wrapper.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@@CAIRO_TREE@/src/$(DEPDIR)/cairo-surface.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@@CAIRO_TREE@/src/$(DEPDIR)/cairo-svg-surface.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@@CAIRO_TREE@/src/$(DEPDIR)/cairo-tag-attributes.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@@CAIRO_TREE@/src/$(DEPDIR)/cairo-tag-stack.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@@CAIRO_TREE@/src/$(DEPDIR)/cairo-time.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@@CAIRO_TREE@/src/$(DEPDIR)/cairo-tor-scan-converter.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@@CAIRO_TREE@/src/$(DEPDIR)/cairo-tor22-scan-converter.Po@am__quote@ # am--include-marker
@@ -2480,6 +2504,7 @@ distclean: distclean-recursive
-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 @@ distclean: distclean-recursive
-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 @@ maintainer-clean: maintainer-clean-recursive
-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 @@ maintainer-clean: maintainer-clean-recursive
-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
diff --git a/Build/source/libs/cairo/README b/Build/source/libs/cairo/README
index 297acbcd9be..6d35a295b10 100644
--- a/Build/source/libs/cairo/README
+++ b/Build/source/libs/cairo/README
@@ -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 @@ been translated into equivalent test in libs/cairo/configure.ac.
2012-11-10 Taco Hoekwater <taco@metatex.org>
2013-04-15 Peter Breitenlohner <peb@mppmu.mpg.de>
-2017-12-07 Akira Kakuto <kakuto@fuk.kindai.ac.jp>
+2018-10-20 Akira Kakuto <kakuto@fuk.kindai.ac.jp>
diff --git a/Build/source/libs/cairo/TLpatches/ChangeLog b/Build/source/libs/cairo/TLpatches/ChangeLog
index b8ee20cf6b0..8be6faef5d8 100644
--- a/Build/source/libs/cairo/TLpatches/ChangeLog
+++ b/Build/source/libs/cairo/TLpatches/ChangeLog
@@ -1,3 +1,7 @@
+2018-10-20 Akira Kakuto <kakuto@fuk.kindai.ac.jp>
+
+ Import cairo-1.16.0.
+
2017-12-07 Akira Kakuto <kakuto@fuk.kindai.ac.jp>
Import cairo-1.14.12.
diff --git a/Build/source/libs/cairo/TLpatches/TL-Changes b/Build/source/libs/cairo/TLpatches/TL-Changes
index 94ffe89d6ac..9259b0f9de8 100644
--- a/Build/source/libs/cairo/TLpatches/TL-Changes
+++ b/Build/source/libs/cairo/TLpatches/TL-Changes
@@ -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 @@ Removed unused dirs:
doc
perf
src/drm
- src/skia
src/win32
test
util
diff --git a/Build/source/libs/cairo/cairo-src/BUGS b/Build/source/libs/cairo/cairo-src/BUGS
index ef044046d3e..452d523006f 100644
--- a/Build/source/libs/cairo/cairo-src/BUGS
+++ b/Build/source/libs/cairo/cairo-src/BUGS
@@ -12,7 +12,7 @@ which you prefer:
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 @@ which you prefer:
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 @@ in getting the bug fixed sooner):
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.
diff --git a/Build/source/libs/cairo/cairo-src/HACKING b/Build/source/libs/cairo/cairo-src/HACKING
index aba2c545bb9..bc97f53248a 100644
--- a/Build/source/libs/cairo/cairo-src/HACKING
+++ b/Build/source/libs/cairo/cairo-src/HACKING
@@ -24,7 +24,7 @@ Contact
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 @@ Mailing Lists
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 @@ Bug Tracking System
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 @@ Version Control System
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 @@ See doc/public/README for more information.
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/.
diff --git a/Build/source/libs/cairo/cairo-src/INSTALL b/Build/source/libs/cairo/cairo-src/INSTALL
index 9db68dee2ba..f25f8f34d3b 100644
--- a/Build/source/libs/cairo/cairo-src/INSTALL
+++ b/Build/source/libs/cairo/cairo-src/INSTALL
@@ -140,11 +140,11 @@ itself), then you're in the right place and should read on.
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.
diff --git a/Build/source/libs/cairo/cairo-src/NEWS b/Build/source/libs/cairo/cairo-src/NEWS
index c0b5db5b1a6..a50b0a001c3 100644
--- a/Build/source/libs/cairo/cairo-src/NEWS
+++ b/Build/source/libs/cairo/cairo-src/NEWS
@@ -1,20 +1,290 @@
-Release 1.14.12 (2017-06-13 Bryce Harrington <bryce@osg.samsung.com>)
+Release 1.16.0 (2018-10-19 Bryce Harrington <bryce@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@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
+
+Dependency Changes
+------------------
None
+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@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@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
@@ -25,35 +295,114 @@ None
Bug Fixes
---------
-* 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 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)
-* Fix undefined-behavior with integer math.
-* Fix various warnings and typos
+* 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)
+* 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.15.8 (2017-08-29 Bryce Harrington <bryce@osg.samsung.com>)
+========================================================================
+This small snapshot provides new colored emoji glyph support, and a
+handful of minor fixes.
+For a complete log of changes, please see
-Release 1.14.10 (2017-06-13 Bryce Harrington <bryce@osg.samsung.com>)
-========================================================================
-Bugfix release rolling up backported fixes for the past half year.
+ https://cairographics.org/releases/ChangeLog.1.15.8
-For a complete log of changes since 1.14.8, please see:
+Features and Enhancements
+-------------------------
+* Support colored emoji glyphs, stored as PNG images in OpenType fonts.
- http://cairographics.org/releases/ChangeLog.cairo-1.14.10
+API Changes
+-----------
+None
-Features
---------
+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@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 @@ None
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,39 +425,70 @@ Bug Fixes
ignore errors for certain requests, to make sure all pending errors
are handled first.
-* For opentype fonts, always use gid to lookup glyph.
-
-* If glyph 0 used for rendering, remap to different index.
-
-* Set font size to em size when retrieving unhinted metrics.
+* Fix text-glyph-range for quartz-font. Use 0xFFFF instead of 0 for
+ invalid index tracking.
-* Flush ASCII85Decode file after use with Postscript files.
+* Fix handling of Supplementary Multilingual Plane (SMP) Unicode
+ characters in quartz-font.
-* pdf: Don't fail subsetting if unable to convert utf8 to utf16.
+* Fix various issues in the drm backend including updating API usage and
+ general code cleanup.
-* For truetype, reverse cmap search should end when 0xffff- 0xffff range
- reached.
-
-* Fix bug in line wrapping with the PDF operators.
+* Clarify documentation regarding device scale inheritance and the units
+ used in cairo_surface_create_similar_image.
+ Bug #99094.
-* Fix an off by one check in cairo-image-info.c.
+Release 1.15.4 (2016-12-9 Bryce Harrington <bryce@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.
-Release 1.14.8 (2016-12-07 Bryce Harrington <bryce@osg.samsung.com>)
-========================================================================
-Bugfix release rolling up backported fixes for the past year.
+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.
-For a complete log of changes since 1.14.6, please see:
+For a complete log of changes since the last release, please see:
- http://cairographics.org/releases/ChangeLog.cairo-1.14.8
+ https://cairographics.org/releases/ChangeLog.1.15.4
Features
--------
-None
+* 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
+
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
------------------
@@ -124,22 +500,131 @@ None
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@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@osg.samsung.com>)
========================================================================
@@ -147,7 +632,7 @@ Simple bugfix release to fix one Windows issue.
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,9 +667,8 @@ cleanup of warnings and memory leaks, correction of misspellings,
updates to documentation, etc.
For a complete log of changes since 1.14.2, please see:
-
- http://cairographics.org/releases/ChangeLog.cairo-1.14.4
-
+
+ https://cairographics.org/releases/ChangeLog.cairo-1.14.4
Features
--------
@@ -260,7 +744,7 @@ Bug Fixes
with XCB.
-Release 1.14.2 (2014-03-09 Bryce Harrington <bryce@osg.samsung.com>)
+Release 1.14.2 (2015-03-09 Bryce Harrington <bryce@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 @@ Bug Fixes
(fdo bugs #89338, #89340, #89356, #89354)
* Fix various documentation warnings and errors
+
Release 1.14.0 (2014-10-13 Bryce Harrington <bryce@osg.samsung.com>)
====================================================================
Hard to believe it's been over a year since our last release, but it's
@@ -836,7 +1321,7 @@ Bug fixes
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,7 +1329,7 @@ Bug fixes
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@chris-wilson.co.uk>)
@@ -864,7 +1349,7 @@ Bug fixes
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 @@ drawing commands made by an application. This can be used to inspecting
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,7 +1879,7 @@ API additions
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
-----------------------------
@@ -1599,10 +2084,10 @@ New experimental backends:
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,14 +2286,14 @@ A few FreeType font handling bugs were fixed:
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
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 @@ Build fixes
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 @@ Invalid referencing of patterns in the Quartz backend:
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 @@ Fix display of user fonts as exercised by proposed support for type3
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 @@ etc.).
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 @@ extents of transformed, filtered surfaces (Owen Taylor, Carl Worth,
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 @@ xlib: Faster bookkeeping (Karl Tomlinson)
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 @@ xlib: Faster bookkeeping (Karl Tomlinson)
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 @@ This fix has been tested to resolve the bugs posted here, (for both
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 @@ New dependency on external pixman library (Thanks, Søren!)
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 @@ to, (and we could use help from users that have access to misbehaving
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 @@ Rendering with CAIRO_ANTIALIAS_NONE has been fixed to be more
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 @@ general
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 @@ Rename ATSUI font backend to Quartz font backend. This affects the
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 @@ cairo-svg
---------
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 @@ cairo_show_text()/cairo_show_glyphs().
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 @@ Add new API for efficiently using image data as a source:
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 @@ So users will need to acquire and build pixman before being able to
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 @@ complain that some cleanup work is already done, but there you have
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 @@ bugs had perhaps never been hit by any users. But at least one was
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 @@ notes on using it:
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 @@ PDF:
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 @@ Critical fixes
• 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 @@ Other bug fixes
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 @@ several improvements. The bug fixes in this snapshot include:
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 @@ performance improvements are as follows:
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 @@ here for such a short time period.
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 @@ affected X servers that do not provide the Render extension and that
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 @@ was also exacerbated by a KDE migration bug that caused antialiasing
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 @@ than 72.0 would lead to incorrect results, (larger values would lead
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 @@ practice, and it was not intentional to introduce a semantic
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 @@ destination surface would not be preserved to the intermediate
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 @@ to the X server, (such as a remote X server over an ssh
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 @@ freetype library is not required to use the pdf backend on the win32
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 @@ Kent notices that with the PDF backend in cairo 1.2.0 as soon as a
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 @@ And at least the following bugs have been fixed:
* 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 @@ This is the third in a series of snapshots working toward the imminent
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 @@ This is the second in a series of snapshots working toward the
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 @@ support this use case, we have added 4 new function calls that are
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 @@ Owen Taylor has converted cairo's documentation system to gtk-doc and
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 @@ This is the first snapshot to include a functional win32 backend,
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,14 +7587,14 @@ resolution. Further changes are described below.
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
----------
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,23 +7660,23 @@ Major API changes
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
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 @@ is a port of Keith Packard's fdclock program originally written for
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 @@ Better text support
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.
diff --git a/Build/source/libs/cairo/cairo-src/README b/Build/source/libs/cairo/cairo-src/README
index 0be9947d548..0bcf140121a 100644
--- a/Build/source/libs/cairo/cairo-src/README
+++ b/Build/source/libs/cairo/cairo-src/README
@@ -1,5 +1,5 @@
Cairo - Multi-platform 2D graphics library
-http://cairographics.org
+https://cairographics.org
What is cairo
=============
@@ -35,25 +35,25 @@ Where to get more information about cairo
=========================================
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 @@ Supported, "standard" surface backends
------------------------------------
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 @@ Supported, "platform" surface backends
-----------------------------------
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 @@ Supported, "platform" surface backends
xcb backend
-----------
- XCB http://xcb.freedesktop.org
+ XCB https://xcb.freedesktop.org
Font backends (required to have at least one)
---------------------------------------------
@@ -181,12 +181,6 @@ Experimental surface backends
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
=========
diff --git a/Build/source/libs/cairo/cairo-src/RELEASING b/Build/source/libs/cairo/cairo-src/RELEASING
index 424902e9b68..8ac926e9bdd 100644
--- a/Build/source/libs/cairo/cairo-src/RELEASING
+++ b/Build/source/libs/cairo/cairo-src/RELEASING
@@ -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 @@ Here are the steps to follow to create a new cairo release:
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 @@ Here are the steps to follow to create a new cairo release:
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 @@ Here are the steps to follow to create a new cairo release:
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 @@ Here are the steps to follow to create a new cairo release:
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 @@ Here are the steps to follow to create a new cairo release:
* 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 @@ Here are the steps to follow to create a new cairo release:
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:
+
+ git push origin master ${THIS_RELEASE}
+
+9) Update master (or the stable branch) version number.
- For Micro releases (X.Y.Z), increment cairo_version_micro to the
- next larger (odd) number in cairo-version.h, commit, and push.
+ 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@cairographics.org and CC
cairo@cairographics.org, gnome-announce-list@gnome.org and
@@ -189,5 +210,8 @@ Here are the steps to follow to create a new cairo release:
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.
+
diff --git a/Build/source/libs/cairo/cairo-src/build/Makefile.am.gtk-doc b/Build/source/libs/cairo/cairo-src/build/Makefile.am.gtk-doc
index c3d642b097b..56aa4957d32 100644
--- a/Build/source/libs/cairo/cairo-src/build/Makefile.am.gtk-doc
+++ b/Build/source/libs/cairo/cairo-src/build/Makefile.am.gtk-doc
@@ -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 @@ EXTRA_DIST += \
$(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 @@ scan-build.stamp: $(HFILE_GLOB) $(CFILE_GLOB) $(EXTRA_HFILES)
$(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 @@ html-build.stamp: sgml.stamp $(DOC_MAIN_SGML_FILE) $(content_files)
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 @@ dist-check-gtkdoc:
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)/
diff --git a/Build/source/libs/cairo/cairo-src/build/Makefile.am.releasing b/Build/source/libs/cairo/cairo-src/build/Makefile.am.releasing
index b17faabce2f..329d49c8ca8 100644
--- a/Build/source/libs/cairo/cairo-src/build/Makefile.am.releasing
+++ b/Build/source/libs/cairo/cairo-src/build/Makefile.am.releasing
@@ -31,7 +31,7 @@ RELEASE_OR_SNAPSHOT = $$(if test "x$(CAIRO_VERSION_MINOR)" = "x$$(echo "$(CAIRO_
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@cairographics.org (and CC gnome-announce-list@gnome.org)
MANUAL_VERSIONED = manual-$(VERSION)
diff --git a/Build/source/libs/cairo/cairo-src/build/Makefile.win32.features b/Build/source/libs/cairo/cairo-src/build/Makefile.win32.features
index 8cb155dc084..b15c4488f88 100644
--- a/Build/source/libs/cairo/cairo-src/build/Makefile.win32.features
+++ b/Build/source/libs/cairo/cairo-src/build/Makefile.win32.features
@@ -11,7 +11,6 @@ CAIRO_HAS_QUARTZ_FONT=0
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_GALLIUM_SURFACE=0
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
diff --git a/Build/source/libs/cairo/cairo-src/build/Makefile.win32.features-h b/Build/source/libs/cairo/cairo-src/build/Makefile.win32.features-h
index 13904cfa9f0..5759b48a3b9 100644
--- a/Build/source/libs/cairo/cairo-src/build/Makefile.win32.features-h
+++ b/Build/source/libs/cairo/cairo-src/build/Makefile.win32.features-h
@@ -38,9 +38,6 @@ endif
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 @@ endif
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
diff --git a/Build/source/libs/cairo/cairo-src/build/aclocal.cairo.m4 b/Build/source/libs/cairo/cairo-src/build/aclocal.cairo.m4
index 44ba5fdf6f5..64c1a2e2fad 100644
--- a/Build/source/libs/cairo/cairo-src/build/aclocal.cairo.m4
+++ b/Build/source/libs/cairo/cairo-src/build/aclocal.cairo.m4
@@ -165,7 +165,7 @@ AC_DEFUN([CAIRO_CHECK_NATIVE_ATOMIC_PRIMITIVES],
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 @@ int atomic_cmpxchg(int i, int j, int k) { return __atomic_compare_exchange_n(&i,
[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 @@ AC_DEFUN([CAIRO_CHECK_ATOMIC_OP_NEEDS_MEMORY_BARRIER],
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
])
diff --git a/Build/source/libs/cairo/cairo-src/build/aclocal.float.m4 b/Build/source/libs/cairo/cairo-src/build/aclocal.float.m4
index ca14ea37707..85adf6d5f45 100644
--- a/Build/source/libs/cairo/cairo-src/build/aclocal.float.m4
+++ b/Build/source/libs/cairo/cairo-src/build/aclocal.float.m4
@@ -12,7 +12,7 @@ AC_DEFUN([AX_C_FLOAT_WORDS_BIGENDIAN],
[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
diff --git a/Build/source/libs/cairo/cairo-src/build/aclocal.pkg.m4 b/Build/source/libs/cairo/cairo-src/build/aclocal.pkg.m4
index cf90a967880..8b9fda90930 100644
--- a/Build/source/libs/cairo/cairo-src/build/aclocal.pkg.m4
+++ b/Build/source/libs/cairo/cairo-src/build/aclocal.pkg.m4
@@ -146,7 +146,7 @@ path to pkg-config.
_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
diff --git a/Build/source/libs/cairo/cairo-src/build/configure.ac.features b/Build/source/libs/cairo/cairo-src/build/configure.ac.features
index 77f20358889..e0a46069c82 100644
--- a/Build/source/libs/cairo/cairo-src/build/configure.ac.features
+++ b/Build/source/libs/cairo/cairo-src/build/configure.ac.features
@@ -369,7 +369,7 @@ AC_DEFUN([CAIRO_REPORT],
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 @@ AC_DEFUN([CAIRO_REPORT],
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"
diff --git a/Build/source/libs/cairo/cairo-src/build/configure.ac.system b/Build/source/libs/cairo/cairo-src/build/configure.ac.system
index 915b42b4636..def75cdc1fc 100644
--- a/Build/source/libs/cairo/cairo-src/build/configure.ac.system
+++ b/Build/source/libs/cairo/cairo-src/build/configure.ac.system
@@ -108,7 +108,7 @@ AC_CHECK_HEADER(fenv.h,
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([[
diff --git a/Build/source/libs/cairo/cairo-src/build/configure.ac.tools b/Build/source/libs/cairo/cairo-src/build/configure.ac.tools
index a24dbcecb91..1fd2d3df825 100644
--- a/Build/source/libs/cairo/cairo-src/build/configure.ac.tools
+++ b/Build/source/libs/cairo/cairo-src/build/configure.ac.tools
@@ -12,7 +12,7 @@ dnl ===========================================================================
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
diff --git a/Build/source/libs/cairo/cairo-src/build/gtk-doc.m4 b/Build/source/libs/cairo/cairo-src/build/gtk-doc.m4
index 36755432b50..2d12f01f4b9 100644
--- a/Build/source/libs/cairo/cairo-src/build/gtk-doc.m4
+++ b/Build/source/libs/cairo/cairo-src/build/gtk-doc.m4
@@ -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
diff --git a/Build/source/libs/cairo/cairo-src/cairo-version.h b/Build/source/libs/cairo/cairo-src/cairo-version.h
index 1f17dd6c6ba..512cfa27907 100644
--- a/Build/source/libs/cairo/cairo-src/cairo-version.h
+++ b/Build/source/libs/cairo/cairo-src/cairo-version.h
@@ -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
diff --git a/Build/source/libs/cairo/cairo-src/config.h.in b/Build/source/libs/cairo/cairo-src/config.h.in
index 5bb49725685..812ef575abb 100644
--- a/Build/source/libs/cairo/cairo-src/config.h.in
+++ b/Build/source/libs/cairo/cairo-src/config.h.in
@@ -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,14 +137,18 @@
/* 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
/* 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
diff --git a/Build/source/libs/cairo/cairo-src/configure.ac b/Build/source/libs/cairo/cairo-src/configure.ac
index 2ce19599e30..5e33c96ea8b 100644
--- a/Build/source/libs/cairo/cairo-src/configure.ac
+++ b/Build/source/libs/cairo/cairo-src/configure.ac
@@ -2,9 +2,9 @@ AC_PREREQ([2.63])
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_SRCDIR(src/cairo.h)
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 @@ if test "x$have_dlsym" = "xyes"; then
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 @@ CAIRO_ENABLE_SURFACE_BACKEND(xlib_xrender, Xlib Xrender, auto, [
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,14 +164,14 @@ dnl ===========================================================================
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, [
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 @@ CAIRO_ENABLE_FUNCTIONS(xcb_shm, XCB/SHM, auto, [
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 @@ AM_CONDITIONAL(CAIRO_CAN_TEST_WIN32_PRINTING_SURFACE, test "x$test_win32_printin
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 @@ CAIRO_ENABLE_SURFACE_BACKEND(beos, BeOS/Zeta, no, [
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 @@ CAIRO_ENABLE_SURFACE_BACKEND(glesv2, OpenGLESv2, no, [
])
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 @@ dnl ===========================================================================
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,7 +556,18 @@ if test "x$use_ft" = "xyes"; then
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"
@@ -664,7 +687,7 @@ dnl ===========================================================================
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 @@ dnl Build gobject integration library
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 ===========================================================================
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"])
diff --git a/Build/source/libs/cairo/cairo-src/src/Makefile.am.features b/Build/source/libs/cairo/cairo-src/src/Makefile.am.features
index c58ac23da4e..47c95db1f91 100644
--- a/Build/source/libs/cairo/cairo-src/src/Makefile.am.features
+++ b/Build/source/libs/cairo/cairo-src/src/Makefile.am.features
@@ -193,22 +193,6 @@ if CAIRO_HAS_WIN32_FONT
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 @@ if CAIRO_HAS_GLESV2_SURFACE
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)
diff --git a/Build/source/libs/cairo/cairo-src/src/Makefile.sources b/Build/source/libs/cairo/cairo-src/src/Makefile.sources
index fac24d79d8a..096a3bcfaad 100644
--- a/Build/source/libs/cairo/cairo-src/src/Makefile.sources
+++ b/Build/source/libs/cairo/cairo-src/src/Makefile.sources
@@ -64,10 +64,10 @@ cairo_private = \
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_private = \
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_private = \
cairo-rtree-private.h \
cairo-scaled-font-private.h \
cairo-slope-private.h \
- cairo-spans-private.h \
cairo-spans-compositor-private.h \
+ cairo-spans-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-subsurface-inline.h \
- cairo-surface-subsurface-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-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_sources = \
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.c \
cairo-boxes-intersect.c \
- cairo.c \
+ cairo-boxes.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_sources = \
cairo-error.c \
cairo-fallback-compositor.c \
cairo-fixed.c \
- cairo-font-face.c \
- cairo-font-face-twin.c \
cairo-font-face-twin-data.c \
+ cairo-font-face-twin.c \
+ cairo-font-face.c \
cairo-font-options.c \
- cairo-freelist.c \
cairo-freed-pool.c \
+ cairo-freelist.c \
cairo-gstate.c \
cairo-hash.c \
cairo-hull.c \
@@ -180,10 +180,10 @@ cairo_sources = \
cairo-image-surface.c \
cairo-line.c \
cairo-lzw.c \
- cairo-matrix.c \
cairo-mask-compositor.c \
- cairo-mesh-pattern-rasterizer.c \
+ cairo-matrix.c \
cairo-mempool.c \
+ cairo-mesh-pattern-rasterizer.c \
cairo-misc.c \
cairo-mono-scan-converter.c \
cairo-mutex.c \
@@ -192,20 +192,20 @@ cairo_sources = \
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_sources = \
cairo-scaled-font.c \
cairo-shape-mask-compositor.c \
cairo-slope.c \
- cairo-spans.c \
cairo-spans-compositor.c \
+ cairo-spans.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_sources = \
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_egl_sources =
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_deflate_stream_sources = cairo-deflate-stream.c
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 @@ cairo_win32_font_sources = \
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_sources = cairo-gl-composite.c \
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-spans-compositor.c \
- cairo-gl-traps-compositor.c \
cairo-gl-source.c \
- cairo-gl-surface.c
+ cairo-gl-spans-compositor.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_directfb_sources = cairo-directfb-surface.c
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 \
diff --git a/Build/source/libs/cairo/cairo-src/src/Makefile.win32.features b/Build/source/libs/cairo/cairo-src/src/Makefile.win32.features
index 2274f4ad6cf..377d6dd12a8 100644
--- a/Build/source/libs/cairo/cairo-src/src/Makefile.win32.features
+++ b/Build/source/libs/cairo/cairo-src/src/Makefile.win32.features
@@ -197,22 +197,6 @@ ifeq ($(CAIRO_HAS_WIN32_FONT),1)
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 @@ ifeq ($(CAIRO_HAS_GLESV2_SURFACE),1)
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)
diff --git a/Build/source/libs/cairo/cairo-src/src/cairo-analysis-surface.c b/Build/source/libs/cairo/cairo-src/src/cairo-analysis-surface.c
index 8516094c200..c4f9a6d3551 100644
--- a/Build/source/libs/cairo/cairo-src/src/cairo-analysis-surface.c
+++ b/Build/source/libs/cairo/cairo-src/src/cairo-analysis-surface.c
@@ -118,11 +118,11 @@ attach_proxy (cairo_surface_t *source,
{
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 @@ detach_proxy (cairo_surface_t *proxy)
}
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 @@ _add_operation (cairo_analysis_surface_t *surface,
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 @@ _cairo_analysis_surface_operation_extents (cairo_analysis_surface_t *surface,
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 @@ static cairo_int_status_t
_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 @@ _cairo_analysis_surface_paint (void *abstract_surface,
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_analysis_surface_mask (void *abstract_surface,
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,18 +455,24 @@ _cairo_analysis_surface_mask (void *abstract_surface,
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;
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 @@ _cairo_analysis_surface_mask (void *abstract_surface,
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 @@ _cairo_analysis_surface_mask (void *abstract_surface,
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 @@ _cairo_analysis_surface_mask (void *abstract_surface,
}
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 @@ _cairo_analysis_surface_stroke (void *abstract_surface,
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_analysis_surface_fill (void *abstract_surface,
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 @@ _cairo_analysis_surface_fill (void *abstract_surface,
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 @@ _cairo_analysis_surface_show_glyphs (void *abstract_surface,
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 @@ _cairo_analysis_surface_show_text_glyphs (void *abstract_surface,
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 @@ _cairo_analysis_surface_show_text_glyphs (void *abstract_surface,
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 @@ static const cairo_surface_backend_t cairo_analysis_surface_backend = {
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 @@ _cairo_analysis_surface_create (cairo_surface_t *target)
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_analysis_surface_create (cairo_surface_t *target)
_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_null_surface_create (cairo_content_t content)
{
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_null_surface_create (cairo_content_t content)
_cairo_surface_init (surface,
&cairo_null_surface_backend,
NULL, /* device */
- content);
+ content,
+ TRUE); /* is_vector */
return surface;
}
diff --git a/Build/source/libs/cairo/cairo-src/src/cairo-atomic-private.h b/Build/source/libs/cairo/cairo-src/src/cairo-atomic-private.h
index 11b2887a147..46761856fac 100644
--- a/Build/source/libs/cairo/cairo-src/src/cairo-atomic-private.h
+++ b/Build/source/libs/cairo/cairo-src/src/cairo-atomic-private.h
@@ -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 @@ _cairo_atomic_int_get (cairo_atomic_int_t *x)
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 @@ _cairo_atomic_ptr_cmpxchg_return_old_impl(void **x, void *oldv, void *newv)
#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,16 +170,24 @@ _cairo_atomic_int_get (cairo_atomic_int_t *x)
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)
{
__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 long long cairo_atomic_intptr_t;
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 unsigned long long cairo_atomic_intptr_t;
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 @@ _cairo_atomic_ptr_cmpxchg_return_old_impl (void **x, void *oldv, void *newv);
#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 @@ _cairo_atomic_ptr_cmpxchg_return_old_fallback(void **x, void *oldv, void *newv)
(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
diff --git a/Build/source/libs/cairo/cairo-src/src/cairo-atomic.c b/Build/source/libs/cairo/cairo-src/src/cairo-atomic.c
index 909cfea4925..2af50cd3878 100644
--- a/Build/source/libs/cairo/cairo-src/src/cairo-atomic.c
+++ b/Build/source/libs/cairo/cairo-src/src/cairo-atomic.c
@@ -101,6 +101,20 @@ _cairo_atomic_int_get (cairo_atomic_intptr_t *x)
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
diff --git a/Build/source/libs/cairo/cairo-src/src/cairo-backend-private.h b/Build/source/libs/cairo/cairo-src/src/cairo-backend-private.h
index b05eca59ab3..67607c12f3a 100644
--- a/Build/source/libs/cairo/cairo-src/src/cairo-backend-private.h
+++ b/Build/source/libs/cairo/cairo-src/src/cairo-backend-private.h
@@ -172,6 +172,9 @@ struct _cairo_backend {
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
diff --git a/Build/source/libs/cairo/cairo-src/src/cairo-base64-stream.c b/Build/source/libs/cairo/cairo-src/src/cairo-base64-stream.c
index 636431372b5..6352545f785 100644
--- a/Build/source/libs/cairo/cairo-src/src/cairo-base64-stream.c
+++ b/Build/source/libs/cairo/cairo-src/src/cairo-base64-stream.c
@@ -125,7 +125,7 @@ _cairo_base64_stream_create (cairo_output_stream_t *output)
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;
diff --git a/Build/source/libs/cairo/cairo-src/src/cairo-base85-stream.c b/Build/source/libs/cairo/cairo-src/src/cairo-base85-stream.c
index f81affb49ea..3202f1e5fb4 100644
--- a/Build/source/libs/cairo/cairo-src/src/cairo-base85-stream.c
+++ b/Build/source/libs/cairo/cairo-src/src/cairo-base85-stream.c
@@ -114,7 +114,7 @@ _cairo_base85_stream_create (cairo_output_stream_t *output)
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;
diff --git a/Build/source/libs/cairo/cairo-src/src/cairo-bentley-ottmann-rectangular.c b/Build/source/libs/cairo/cairo-src/src/cairo-bentley-ottmann-rectangular.c
index cb2e30c8a96..65f95d79705 100644
--- a/Build/source/libs/cairo/cairo-src/src/cairo-bentley-ottmann-rectangular.c
+++ b/Build/source/libs/cairo/cairo-src/src/cairo-bentley-ottmann-rectangular.c
@@ -593,12 +593,6 @@ sweep_line_insert (sweep_line_t *sweep, rectangle_t *rectangle)
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 @@ _cairo_bentley_ottmann_tessellate_rectangular (rectangle_t **rectangles,
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,10 +674,19 @@ _cairo_bentley_ottmann_tessellate_rectangular_traps (cairo_traps_t *traps,
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");
diff --git a/Build/source/libs/cairo/cairo-src/src/cairo-bentley-ottmann.c b/Build/source/libs/cairo/cairo-src/src/cairo-bentley-ottmann.c
index 91e41f9c3cb..2011e73bd2d 100644
--- a/Build/source/libs/cairo/cairo-src/src/cairo-bentley-ottmann.c
+++ b/Build/source/libs/cairo/cairo-src/src/cairo-bentley-ottmann.c
@@ -1484,10 +1484,13 @@ _cairo_bentley_ottmann_tessellate_polygon (cairo_traps_t *traps,
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 @@ _cairo_bentley_ottmann_tessellate_polygon (cairo_traps_t *traps,
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);
}
diff --git a/Build/source/libs/cairo/cairo-src/src/cairo-botor-scan-converter.c b/Build/source/libs/cairo/cairo-src/src/cairo-botor-scan-converter.c
index 515305bf24e..438f96bb86f 100644
--- a/Build/source/libs/cairo/cairo-src/src/cairo-botor-scan-converter.c
+++ b/Build/source/libs/cairo/cairo-src/src/cairo-botor-scan-converter.c
@@ -456,7 +456,7 @@ edges_compare_x_for_y (const cairo_edge_t *a,
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 @@ botor_add_edge (cairo_botor_scan_converter_t *self,
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)
{
diff --git a/Build/source/libs/cairo/cairo-src/src/cairo-box-inline.h b/Build/source/libs/cairo/cairo-src/src/cairo-box-inline.h
index d6b994127e3..59e5a0d5f19 100644
--- a/Build/source/libs/cairo/cairo-src/src/cairo-box-inline.h
+++ b/Build/source/libs/cairo/cairo-src/src/cairo-box-inline.h
@@ -57,6 +57,16 @@ _cairo_box_from_integers (cairo_box_t *box, int x, int y, int w, int h)
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,
diff --git a/Build/source/libs/cairo/cairo-src/src/cairo-boxes-private.h b/Build/source/libs/cairo/cairo-src/src/cairo-boxes-private.h
index d1f9dfcd1e5..fd622aec316 100644
--- a/Build/source/libs/cairo/cairo-src/src/cairo-boxes-private.h
+++ b/Build/source/libs/cairo/cairo-src/src/cairo-boxes-private.h
@@ -92,8 +92,7 @@ _cairo_boxes_extents (const cairo_boxes_t *boxes,
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,
diff --git a/Build/source/libs/cairo/cairo-src/src/cairo-boxes.c b/Build/source/libs/cairo/cairo-src/src/cairo-boxes.c
index 63b68ddfb90..3c5d2a75029 100644
--- a/Build/source/libs/cairo/cairo-src/src/cairo-boxes.c
+++ b/Build/source/libs/cairo/cairo-src/src/cairo-boxes.c
@@ -102,6 +102,17 @@ _cairo_boxes_init_for_array (cairo_boxes_t *boxes,
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 @@ _cairo_boxes_add (cairo_boxes_t *boxes,
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,18 +336,25 @@ _cairo_boxes_clear (cairo_boxes_t *boxes)
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;
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) {
diff --git a/Build/source/libs/cairo/cairo-src/src/cairo-cff-subset.c b/Build/source/libs/cairo/cairo-src/src/cairo-cff-subset.c
index c93a8bd8696..37727eddb45 100644
--- a/Build/source/libs/cairo/cairo-src/src/cairo-cff-subset.c
+++ b/Build/source/libs/cairo/cairo-src/src/cairo-cff-subset.c
@@ -295,20 +295,11 @@ decode_nibble (int n, char *buf)
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);
-
- 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));
+ char *end;
+ int n;
p++;
while (buf + 2 < buf_end) {
@@ -324,19 +315,7 @@ decode_real (unsigned char *p, double *real)
};
*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;
- }
-
- if (sscanf(buf, "%lf", real) != 1)
- *real = 0.0;
+ *real = _cairo_strtod (buffer, &end);
return p;
}
@@ -568,7 +547,7 @@ cff_index_append_copy (cairo_array_t *index,
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_create_operator (int operator,
{
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 @@ cff_dict_set_operands (cairo_hash_table_t *dict,
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 @@ cairo_cff_font_read_name (cairo_cff_font_t *font)
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_cff_font_create_cid_fontdict (cairo_cff_font_t *font)
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 @@ cairo_cff_font_create_cid_fontdict (cairo_cff_font_t *font)
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 @@ cairo_cff_font_subset_font (cairo_cff_font_t *font)
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 @@ cairo_cff_font_generate (cairo_cff_font_t *font,
/* 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 @@ _cairo_cff_font_load_opentype_cff (cairo_cff_font_t *font)
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 @@ _cairo_cff_font_load_cff (cairo_cff_font_t *font)
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,13 +2767,20 @@ _cairo_cff_font_create (cairo_scaled_font_subset_t *scaled_font_subset,
{
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))
@@ -2995,7 +2981,7 @@ _cairo_cff_subset_init (cairo_cff_subset_t *cff_subset,
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 @@ _cairo_cff_scaled_font_is_cid_cff (cairo_scaled_font_t *scaled_font)
(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 @@ _cairo_cff_scaled_font_is_cid_cff (cairo_scaled_font_t *scaled_font)
(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_cff_font_fallback_create (cairo_scaled_font_subset_t *scaled_font_subset
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 @@ cairo_cff_font_fallback_generate (cairo_cff_font_t *font,
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 @@ _cairo_cff_fallback_init (cairo_cff_subset_t *cff_subset,
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;
diff --git a/Build/source/libs/cairo/cairo-src/src/cairo-clip-boxes.c b/Build/source/libs/cairo/cairo-src/src/cairo-clip-boxes.c
index 7bcbeb1918a..aaddeb7f7be 100644
--- a/Build/source/libs/cairo/cairo-src/src/cairo-clip-boxes.c
+++ b/Build/source/libs/cairo/cairo-src/src/cairo-clip-boxes.c
@@ -119,11 +119,7 @@ _cairo_clip_contains_rectangle (const cairo_clip_t *clip,
{
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 @@ _cairo_clip_intersect_box (cairo_clip_t *clip,
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 @@ _cairo_clip_intersect_boxes (cairo_clip_t *clip,
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 @@ _cairo_clip_intersect_rectangle (cairo_clip_t *clip,
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 @@ _cairo_clip_from_boxes (const cairo_boxes_t *boxes)
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);
diff --git a/Build/source/libs/cairo/cairo-src/src/cairo-clip-tor-scan-converter.c b/Build/source/libs/cairo/cairo-src/src/cairo-clip-tor-scan-converter.c
index e32a5a9d9c7..2ac1d32b138 100644
--- a/Build/source/libs/cairo/cairo-src/src/cairo-clip-tor-scan-converter.c
+++ b/Build/source/libs/cairo/cairo-src/src/cairo-clip-tor-scan-converter.c
@@ -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 @@ _pool_chunk_create(struct pool *pool, size_t size)
{
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));
diff --git a/Build/source/libs/cairo/cairo-src/src/cairo-clip.c b/Build/source/libs/cairo/cairo-src/src/cairo-clip.c
index 0df9b06bf60..d499bf0adec 100644
--- a/Build/source/libs/cairo/cairo-src/src/cairo-clip.c
+++ b/Build/source/libs/cairo/cairo-src/src/cairo-clip.c
@@ -62,7 +62,7 @@ _cairo_clip_path_create (cairo_clip_t *clip)
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 @@ _cairo_clip_create (void)
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 @@ _cairo_rectangle_list_create_in_error (cairo_status_t status)
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 @@ _cairo_clip_copy_rectangle_list (cairo_clip_t *clip, cairo_gstate_t *gstate)
}
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);
diff --git a/Build/source/libs/cairo/cairo-src/src/cairo-cogl-context.c b/Build/source/libs/cairo/cairo-src/src/cairo-cogl-context.c
index 0116b0a5a93..c3227805766 100644
--- a/Build/source/libs/cairo/cairo-src/src/cairo-cogl-context.c
+++ b/Build/source/libs/cairo/cairo-src/src/cairo-cogl-context.c
@@ -755,7 +755,7 @@ _cairo_cogl_context_create (void *target)
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));
}
diff --git a/Build/source/libs/cairo/cairo-src/src/cairo-cogl-gradient.c b/Build/source/libs/cairo/cairo-src/src/cairo-cogl-gradient.c
index f8c80041629..0923e3b6d95 100644
--- a/Build/source/libs/cairo/cairo-src/src/cairo-cogl-gradient.c
+++ b/Build/source/libs/cairo/cairo-src/src/cairo-cogl-gradient.c
@@ -397,7 +397,7 @@ _cairo_cogl_get_linear_gradient (cairo_cogl_device_t *device,
}
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 @@ _cairo_cogl_get_linear_gradient (cairo_cogl_device_t *device,
} 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;
diff --git a/Build/source/libs/cairo/cairo-src/src/cairo-cogl-surface.c b/Build/source/libs/cairo/cairo-src/src/cairo-cogl-surface.c
index c57fd7f433c..2f7ed58d333 100644
--- a/Build/source/libs/cairo/cairo-src/src/cairo-cogl-surface.c
+++ b/Build/source/libs/cairo/cairo-src/src/cairo-cogl-surface.c
@@ -517,7 +517,7 @@ _cairo_cogl_surface_allocate_buffer_space (cairo_cogl_surface_t *surface,
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_cogl_get_path_stroke_meta (cairo_cogl_surface_t *surface,
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 @@ _cairo_cogl_get_path_fill_meta (cairo_cogl_surface_t *surface)
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 @@ _cairo_cogl_surface_create_full (cairo_cogl_device_t *dev,
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_cogl_surface_create_full (cairo_cogl_device_t *dev,
_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;
}
diff --git a/Build/source/libs/cairo/cairo-src/src/cairo-compiler-private.h b/Build/source/libs/cairo/cairo-src/src/cairo-compiler-private.h
index 216e71b4ec3..d982c101d04 100644
--- a/Build/source/libs/cairo/cairo-src/src/cairo-compiler-private.h
+++ b/Build/source/libs/cairo/cairo-src/src/cairo-compiler-private.h
@@ -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)
*
diff --git a/Build/source/libs/cairo/cairo-src/src/cairo-composite-rectangles.c b/Build/source/libs/cairo/cairo-src/src/cairo-composite-rectangles.c
index 6c3e97d4a97..f102eddbce9 100644
--- a/Build/source/libs/cairo/cairo-src/src/cairo-composite-rectangles.c
+++ b/Build/source/libs/cairo/cairo-src/src/cairo-composite-rectangles.c
@@ -97,7 +97,8 @@ _cairo_composite_rectangles_init (cairo_composite_rectangles_t *extents,
_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 @@ static cairo_int_status_t
_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_composite_rectangles_intersect_mask_extents (cairo_composite_rectangles_t
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 @@ _cairo_composite_rectangles_init_for_mask (cairo_composite_rectangles_t *extents
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 @@ _cairo_composite_rectangles_init_for_stroke (cairo_composite_rectangles_t *exten
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);
}
diff --git a/Build/source/libs/cairo/cairo-src/src/cairo-damage.c b/Build/source/libs/cairo/cairo-src/src/cairo-damage.c
index 63191fee95d..97d9fe9095b 100644
--- a/Build/source/libs/cairo/cairo-src/src/cairo-damage.c
+++ b/Build/source/libs/cairo/cairo-src/src/cairo-damage.c
@@ -51,7 +51,7 @@ _cairo_damage_create (void)
{
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 @@ _cairo_damage_add_boxes(cairo_damage_t *damage,
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 @@ _cairo_damage_reduce (cairo_damage_t *damage)
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;
diff --git a/Build/source/libs/cairo/cairo-src/src/cairo-debug.c b/Build/source/libs/cairo/cairo-src/src/cairo-debug.c
index e7ffe48d28c..6005060d4a0 100644
--- a/Build/source/libs/cairo/cairo-src/src/cairo-debug.c
+++ b/Build/source/libs/cairo/cairo-src/src/cairo-debug.c
@@ -86,6 +86,8 @@ cairo_debug_reset_static_data (void)
_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 @@ _print_close (void *closure)
}
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 @@ _cairo_debug_print_polygon (FILE *stream, cairo_polygon_t *polygon)
}
}
+
+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);
+}
diff --git a/Build/source/libs/cairo/cairo-src/src/cairo-default-context.c b/Build/source/libs/cairo/cairo-src/src/cairo-default-context.c
index 1e5067bf1b8..985215ff739 100644
--- a/Build/source/libs/cairo/cairo-src/src/cairo-default-context.c
+++ b/Build/source/libs/cairo/cairo-src/src/cairo-default-context.c
@@ -1156,6 +1156,24 @@ _cairo_default_context_copy_page (void *abstract_cr)
}
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 @@ static const cairo_backend_t _cairo_default_context_backend = {
_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 @@ _cairo_default_context_create (void *target)
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));
}
diff --git a/Build/source/libs/cairo/cairo-src/src/cairo-deflate-stream.c b/Build/source/libs/cairo/cairo-src/src/cairo-deflate-stream.c
index ae23bda9472..b51a6399cd0 100644
--- a/Build/source/libs/cairo/cairo-src/src/cairo-deflate-stream.c
+++ b/Build/source/libs/cairo/cairo-src/src/cairo-deflate-stream.c
@@ -124,7 +124,7 @@ _cairo_deflate_stream_create (cairo_output_stream_t *output)
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;
diff --git a/Build/source/libs/cairo/cairo-src/src/cairo-device.c b/Build/source/libs/cairo/cairo-src/src/cairo-device.c
index 585a9c1c41f..965c84c6519 100644
--- a/Build/source/libs/cairo/cairo-src/src/cairo-device.c
+++ b/Build/source/libs/cairo/cairo-src/src/cairo-device.c
@@ -159,6 +159,10 @@ _cairo_device_create_in_error (cairo_status_t status)
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 @@ _cairo_device_init (cairo_device_t *device,
* @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.
*
diff --git a/Build/source/libs/cairo/cairo-src/src/cairo-directfb-surface.c b/Build/source/libs/cairo/cairo-src/src/cairo-directfb-surface.c
index 5ac64ba98ee..0deedf0d549 100644
--- a/Build/source/libs/cairo/cairo-src/src/cairo-directfb-surface.c
+++ b/Build/source/libs/cairo/cairo-src/src/cairo-directfb-surface.c
@@ -522,7 +522,8 @@ cairo_directfb_surface_create (IDirectFB *dfb, IDirectFBSurface *dfbsurface)
_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);
diff --git a/Build/source/libs/cairo/cairo-src/src/cairo-error-private.h b/Build/source/libs/cairo/cairo-src/src/cairo-error-private.h
index 178078ad614..1ab57ddf846 100644
--- a/Build/source/libs/cairo/cairo-src/src/cairo-error-private.h
+++ b/Build/source/libs/cairo/cairo-src/src/cairo-error-private.h
@@ -94,6 +94,10 @@ enum _cairo_int_status {
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,
diff --git a/Build/source/libs/cairo/cairo-src/src/cairo-font-face-twin.c b/Build/source/libs/cairo/cairo-src/src/cairo-font-face-twin.c
index 2ad26302849..a0855c9f601 100644
--- a/Build/source/libs/cairo/cairo-src/src/cairo-font-face-twin.c
+++ b/Build/source/libs/cairo/cairo-src/src/cairo-font-face-twin.c
@@ -288,7 +288,7 @@ twin_font_face_create_properties (cairo_font_face_t *twin_face)
{
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 @@ twin_scaled_font_compute_properties (cairo_scaled_font_t *scaled_font,
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);
diff --git a/Build/source/libs/cairo/cairo-src/src/cairo-font-face.c b/Build/source/libs/cairo/cairo-src/src/cairo-font-face.c
index 795951b1420..e10a6eac2f2 100644
--- a/Build/source/libs/cairo/cairo-src/src/cairo-font-face.c
+++ b/Build/source/libs/cairo/cairo-src/src/cairo-font-face.c
@@ -111,8 +111,8 @@ _cairo_font_face_init (cairo_font_face_t *font_face,
* @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.
*
diff --git a/Build/source/libs/cairo/cairo-src/src/cairo-font-options.c b/Build/source/libs/cairo/cairo-src/src/cairo-font-options.c
index ad28745e6b9..9aef1407386 100644
--- a/Build/source/libs/cairo/cairo-src/src/cairo-font-options.c
+++ b/Build/source/libs/cairo/cairo-src/src/cairo-font-options.c
@@ -55,7 +55,8 @@ static const cairo_font_options_t _cairo_font_options_nil = {
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 @@ _cairo_font_options_init_default (cairo_font_options_t *options)
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 @@ _cairo_font_options_init_copy (cairo_font_options_t *options,
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_create (void)
{
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 @@ cairo_font_options_copy (const cairo_font_options_t *original)
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 @@ cairo_font_options_copy (const cairo_font_options_t *original)
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 @@ cairo_font_options_destroy (cairo_font_options_t *options)
if (cairo_font_options_status (options))
return;
+ _cairo_font_options_fini (options);
free (options);
}
@@ -226,6 +236,24 @@ cairo_font_options_merge (cairo_font_options_t *options,
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 @@ cairo_font_options_equal (const cairo_font_options_t *options,
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 @@ slim_hidden_def (cairo_font_options_equal);
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 @@ cairo_font_options_get_hint_metrics (const cairo_font_options_t *options)
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;
+}
diff --git a/Build/source/libs/cairo/cairo-src/src/cairo-freed-pool-private.h b/Build/source/libs/cairo/cairo-src/src/cairo-freed-pool-private.h
index 0ec6de3d1f1..8a7af523db3 100644
--- a/Build/source/libs/cairo/cairo-src/src/cairo-freed-pool-private.h
+++ b/Build/source/libs/cairo/cairo-src/src/cairo-freed-pool-private.h
@@ -51,7 +51,7 @@ CAIRO_BEGIN_DECLS
#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 @@ _freed_pool_get (freed_pool_t *pool)
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 @@ _freed_pool_put (freed_pool_t *pool, void *ptr)
{
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;
}
diff --git a/Build/source/libs/cairo/cairo-src/src/cairo-freed-pool.c b/Build/source/libs/cairo/cairo-src/src/cairo-freed-pool.c
index cfdc8e96b05..5b1c4c0bb2c 100644
--- a/Build/source/libs/cairo/cairo-src/src/cairo-freed-pool.c
+++ b/Build/source/libs/cairo/cairo-src/src/cairo-freed-pool.c
@@ -50,13 +50,13 @@ _freed_pool_get_search (freed_pool_t *pool)
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 @@ _freed_pool_put_search (freed_pool_t *pool, void *ptr)
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 @@ _freed_pool_reset (freed_pool_t *pool)
pool->pool[i] = NULL;
}
- pool->top = 0;
+ _cairo_atomic_int_set_relaxed (&pool->top, 0);
}
#endif
diff --git a/Build/source/libs/cairo/cairo-src/src/cairo-freelist-private.h b/Build/source/libs/cairo/cairo-src/src/cairo-freelist-private.h
index 8fe6516f385..f85f6891412 100644
--- a/Build/source/libs/cairo/cairo-src/src/cairo-freelist-private.h
+++ b/Build/source/libs/cairo/cairo-src/src/cairo-freelist-private.h
@@ -133,7 +133,7 @@ _cairo_freepool_free (cairo_freepool_t *freepool, void *ptr)
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 */
diff --git a/Build/source/libs/cairo/cairo-src/src/cairo-freelist.c b/Build/source/libs/cairo/cairo-src/src/cairo-freelist.c
index d596eab81dc..7f2f3b30b81 100644
--- a/Build/source/libs/cairo/cairo-src/src/cairo-freelist.c
+++ b/Build/source/libs/cairo/cairo-src/src/cairo-freelist.c
@@ -61,7 +61,7 @@ _cairo_freelist_alloc (cairo_freelist_t *freelist)
return node;
}
- return malloc (freelist->nodesize);
+ return _cairo_malloc (freelist->nodesize);
}
void *
@@ -80,7 +80,7 @@ _cairo_freelist_free (cairo_freelist_t *freelist, void *voidnode)
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 @@ _cairo_freepool_init (cairo_freepool_t *freepool, unsigned nodesize)
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 @@ _cairo_freepool_fini (cairo_freepool_t *freepool)
pool = next;
}
- VG (VALGRIND_MAKE_MEM_NOACCESS (freepool, sizeof (freepool)));
+ VG (VALGRIND_MAKE_MEM_UNDEFINED (freepool, sizeof (freepool)));
}
void *
@@ -139,7 +139,7 @@ _cairo_freepool_alloc_from_new_pool (cairo_freepool_t *freepool)
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 @@ _cairo_freepool_alloc_from_new_pool (cairo_freepool_t *freepool)
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;
}
diff --git a/Build/source/libs/cairo/cairo-src/src/cairo-ft-font.c b/Build/source/libs/cairo/cairo-src/src/cairo-ft-font.c
index 462d1e25fd8..325dd61b47b 100644
--- a/Build/source/libs/cairo/cairo-src/src/cairo-ft-font.c
+++ b/Build/source/libs/cairo/cairo-src/src/cairo-ft-font.c
@@ -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 @@ struct _cairo_ft_unscaled_font {
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 @@ typedef struct _cairo_ft_options {
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 @@ _ft_to_cairo_error (FT_Error error)
* 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 @@ _cairo_ft_unscaled_font_map_create (void)
* 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_ft_unscaled_font_init (cairo_ft_unscaled_font_t *unscaled,
_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 @@ _cairo_ft_unscaled_font_init (cairo_ft_unscaled_font_t *unscaled,
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 @@ _cairo_ft_unscaled_font_fini (cairo_ft_unscaled_font_t *unscaled)
free (unscaled->filename);
unscaled->filename = NULL;
+ free (unscaled->variations);
+
CAIRO_MUTEX_FINI (unscaled->mutex);
}
@@ -475,7 +519,7 @@ _cairo_ft_unscaled_font_keys_equal (const void *key_a,
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 @@ _cairo_ft_unscaled_font_create_internal (cairo_bool_t from_face,
}
/* 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 @@ static cairo_status_t
_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 @@ _cairo_ft_unscaled_font_lock_face (cairo_ft_unscaled_font_t *unscaled)
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 @@ _compute_xrender_bitmap_size(FT_Bitmap *target,
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 @@ _fill_xrender_bitmap(FT_Bitmap *target,
}
break;
- default: /* FT_PIXEL_MODE_LCD_V */
+ case FT_PIXEL_MODE_LCD_V:
/* convert vertical RGB into ARGB32 */
if (!bgr) {
@@ -1123,6 +1175,15 @@ _fill_xrender_bitmap(FT_Bitmap *target,
}
}
}
+ 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 @@ _get_bitmap_surface (FT_Bitmap *bitmap,
component_alpha = TRUE;
}
break;
-#ifdef FT_LOAD_COLOR
case FT_PIXEL_MODE_BGRA:
stride = width * 4;
if (own_buffer) {
@@ -1240,9 +1300,17 @@ _get_bitmap_surface (FT_Bitmap *bitmap,
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 @@ _render_glyph_outline (FT_Face face,
(*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 @@ _transform_glyph_bitmap (cairo_matrix_t * shape,
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 @@ _get_pattern_ft_options (FcPattern *pattern, cairo_ft_options_t *ret)
#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 @@ _get_pattern_ft_options (FcPattern *pattern, cairo_ft_options_t *ret)
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 @@ _cairo_ft_options_merge (cairo_ft_options_t *options,
}
}
+ 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 @@ _cairo_ft_font_face_scaled_font_create (void *abstract_font_face,
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 @@ _cairo_ft_scaled_glyph_vertical_layout_bearing_fix (void *abstract_font,
}
}
+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 @@ _cairo_ft_scaled_glyph_load_glyph (cairo_ft_scaled_font_t *scaled_font,
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 @@ _cairo_ft_scaled_glyph_init (void *abstract_font,
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 @@ _cairo_ft_scaled_glyph_init (void *abstract_font,
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 @@ _cairo_ft_scaled_glyph_init (void *abstract_font,
&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,16 +2629,35 @@ _cairo_ft_scaled_glyph_init (void *abstract_font,
{
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) {
@@ -2463,7 +2667,7 @@ _cairo_ft_scaled_glyph_init (void *abstract_font,
* 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 @@ _cairo_ft_index_to_ucs4(void *abstract_font,
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 @@ _cairo_ft_load_type1_data (void *abstract_font,
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 @@ static const cairo_scaled_font_backend_t _cairo_ft_scaled_font_backend = {
_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 @@ _cairo_ft_font_face_destroy (void *abstract_face)
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,13 +3255,16 @@ _cairo_ft_font_face_create_for_pattern (FcPattern *pattern)
{
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;
}
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 @@ _cairo_ft_font_face_create (cairo_ft_unscaled_font_t *unscaled,
}
/* 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 @@ _cairo_ft_font_face_create (cairo_ft_unscaled_font_t *unscaled,
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 @@ _cairo_ft_resolve_pattern (FcPattern *pattern,
_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 @@ cairo_ft_font_face_create_for_pattern (FcPattern *pattern)
_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_get_synthesize (cairo_font_face_t *font_face)
* 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 @@ cairo_ft_scaled_font_lock_face (cairo_scaled_font_t *abstract_font)
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
diff --git a/Build/source/libs/cairo/cairo-src/src/cairo-gl-composite.c b/Build/source/libs/cairo/cairo-src/src/cairo-gl-composite.c
index 5b1411472d0..5477ef0d8ac 100644
--- a/Build/source/libs/cairo/cairo-src/src/cairo-gl-composite.c
+++ b/Build/source/libs/cairo/cairo-src/src/cairo-gl-composite.c
@@ -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 @@ void
_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_composite_set_mask (cairo_gl_composite_t *setup,
{
_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 @@ void
_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 @@ _cairo_gl_composite_set_multisample (cairo_gl_composite_t *setup)
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 @@ _cairo_gl_composite_bind_to_shader (cairo_gl_context_t *ctx,
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 @@ _cairo_gl_texture_set_filter (cairo_gl_context_t *ctx,
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 @@ _cairo_gl_texture_set_extend (cairo_gl_context_t *ctx,
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,36 +316,36 @@ _cairo_gl_context_setup_operand (cairo_gl_context_t *ctx,
* 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));
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 @@ _cairo_gl_context_setup_operand (cairo_gl_context_t *ctx,
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 @@ _cairo_gl_context_setup_spans (cairo_gl_context_t *ctx,
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 @@ _cairo_gl_context_destroy_operand (cairo_gl_context_t *ctx,
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 @@ _cairo_gl_context_destroy_operand (cairo_gl_context_t *ctx,
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 @@ _cairo_gl_set_operator (cairo_gl_context_t *ctx,
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 @@ _cairo_gl_set_operator (cairo_gl_context_t *ctx,
}
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 @@ _cairo_gl_composite_begin_component_alpha (cairo_gl_context_t *ctx,
* 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 @@ _cairo_gl_composite_begin_component_alpha (cairo_gl_context_t *ctx,
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 @@ _cairo_gl_composite_setup_clipping (cairo_gl_composite_t *setup,
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 @@ _cairo_gl_set_operands_and_operator (cairo_gl_composite_t *setup,
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 @@ _cairo_gl_composite_begin (cairo_gl_composite_t *setup,
FAIL:
if (unlikely (status))
- status = _cairo_gl_context_release (ctx, status);
+ status = _cairo_gl_context_release (ctx, status);
return status;
}
@@ -800,17 +897,17 @@ _cairo_gl_composite_draw_triangles (cairo_gl_context_t *ctx,
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 @@ _cairo_gl_composite_flush (cairo_gl_context_t *ctx)
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 @@ _cairo_gl_composite_emit_point (cairo_gl_context_t *ctx,
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 @@ _cairo_gl_context_emit_rect (cairo_gl_context_t *ctx,
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 @@ _cairo_gl_context_choose_emit_span (cairo_gl_context_t *ctx)
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 @@ _cairo_gl_composite_emit_glyph_vertex (cairo_gl_context_t *ctx,
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 @@ _cairo_gl_context_choose_emit_glyph (cairo_gl_context_t *ctx)
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_gl_composite_set_operator (cairo_gl_composite_t *setup,
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_gl_composite_set_operator (cairo_gl_composite_t *setup,
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,
diff --git a/Build/source/libs/cairo/cairo-src/src/cairo-gl-device.c b/Build/source/libs/cairo/cairo-src/src/cairo-gl-device.c
index 7235d9ae123..258b4c50dbc 100644
--- a/Build/source/libs/cairo/cairo-src/src/cairo-gl-device.c
+++ b/Build/source/libs/cairo/cairo-src/src/cairo-gl-device.c
@@ -71,7 +71,7 @@ _gl_flush (void *device)
status = _cairo_gl_context_acquire (device, &ctx);
if (unlikely (status))
- return status;
+ return status;
_cairo_gl_composite_flush (ctx);
@@ -79,8 +79,8 @@ _gl_flush (void *device)
_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 @@ test_can_read_bgra (cairo_gl_flavor_t gl_flavor)
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 @@ _cairo_gl_context_init (cairo_gl_context_t *ctx)
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,43 +265,49 @@ _cairo_gl_context_init (cairo_gl_context_t *ctx)
}
#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);
}
#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 @@ _cairo_gl_context_init (cairo_gl_context_t *ctx)
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,13 +357,15 @@ _get_depth_stencil_format (cairo_gl_context_t *ctx)
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
#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 @@ _cairo_gl_ensure_msaa_gles_framebuffer (cairo_gl_context_t *ctx,
}
#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 @@ _cairo_gl_ensure_framebuffer (cairo_gl_context_t *ctx,
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 @@ _cairo_gl_ensure_framebuffer (cairo_gl_context_t *ctx,
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 @@ _cairo_gl_ensure_multisampling (cairo_gl_context_t *ctx,
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 @@ _cairo_gl_ensure_multisampling (cairo_gl_context_t *ctx,
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 @@ _cairo_gl_ensure_msaa_depth_stencil_buffer (cairo_gl_context_t *ctx,
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 @@ _cairo_gl_ensure_msaa_depth_stencil_buffer (cairo_gl_context_t *ctx,
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 @@ _cairo_gl_ensure_msaa_depth_stencil_buffer (cairo_gl_context_t *ctx,
#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 @@ _gl_identity_ortho (GLfloat *m,
#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 @@ bind_multisample_framebuffer (cairo_gl_context_t *ctx,
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 @@ bind_multisample_framebuffer (cairo_gl_context_t *ctx,
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,17 +680,24 @@ bind_multisample_framebuffer (cairo_gl_context_t *ctx,
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)
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 @@ bind_singlesample_framebuffer (cairo_gl_context_t *ctx,
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 @@ bind_singlesample_framebuffer (cairo_gl_context_t *ctx,
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 @@ _cairo_gl_context_bind_framebuffer (cairo_gl_context_t *ctx,
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 @@ _cairo_gl_context_bind_framebuffer (cairo_gl_context_t *ctx,
#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;
diff --git a/Build/source/libs/cairo/cairo-src/src/cairo-gl-dispatch.c b/Build/source/libs/cairo/cairo-src/src/cairo-gl-dispatch.c
index 76c3115ba37..a49199dbb0a 100644
--- a/Build/source/libs/cairo/cairo-src/src/cairo-gl-dispatch.c
+++ b/Build/source/libs/cairo/cairo-src/src/cairo-gl-dispatch.c
@@ -124,7 +124,11 @@ _cairo_gl_dispatch_init_buffers (cairo_gl_dispatch_t *dispatch,
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 @@ _cairo_gl_dispatch_init_shaders (cairo_gl_dispatch_t *dispatch,
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 @@ _cairo_gl_dispatch_init_fbo (cairo_gl_dispatch_t *dispatch,
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 @@ _cairo_gl_dispatch_init_multisampling (cairo_gl_dispatch_t *dispatch,
/* 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"))
diff --git a/Build/source/libs/cairo/cairo-src/src/cairo-gl-glyphs.c b/Build/source/libs/cairo/cairo-src/src/cairo-gl-glyphs.c
index 8a1a548d939..5923af44147 100644
--- a/Build/source/libs/cairo/cairo-src/src/cairo-gl-glyphs.c
+++ b/Build/source/libs/cairo/cairo-src/src/cairo-gl-glyphs.c
@@ -120,10 +120,10 @@ _cairo_gl_glyph_cache_add_glyph (cairo_gl_context_t *ctx,
/* 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 @@ _cairo_gl_glyph_cache_add_glyph (cairo_gl_context_t *ctx,
/* 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 @@ _cairo_gl_glyph_cache_lock (cairo_gl_glyph_cache_t *cache,
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 @@ cairo_gl_context_get_glyph_cache (cairo_gl_context_t *ctx,
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_gl_context_get_glyph_cache (cairo_gl_context_t *ctx,
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 @@ render_glyphs (cairo_gl_surface_t *dst,
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 @@ render_glyphs (cairo_gl_surface_t *dst,
*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 @@ render_glyphs_via_mask (cairo_gl_surface_t *dst,
/* 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 @@ render_glyphs_via_mask (cairo_gl_surface_t *dst,
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 @@ render_glyphs_via_mask (cairo_gl_surface_t *dst,
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);
diff --git a/Build/source/libs/cairo/cairo-src/src/cairo-gl-gradient-private.h b/Build/source/libs/cairo/cairo-src/src/cairo-gl-gradient-private.h
index 77f9bbdc5f5..0d9f41f54b4 100644
--- a/Build/source/libs/cairo/cairo-src/src/cairo-gl-gradient-private.h
+++ b/Build/source/libs/cairo/cairo-src/src/cairo-gl-gradient-private.h
@@ -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
diff --git a/Build/source/libs/cairo/cairo-src/src/cairo-gl-gradient.c b/Build/source/libs/cairo/cairo-src/src/cairo-gl-gradient.c
index ac3292101ec..6107bea1e08 100644
--- a/Build/source/libs/cairo/cairo-src/src/cairo-gl-gradient.c
+++ b/Build/source/libs/cairo/cairo-src/src/cairo-gl-gradient.c
@@ -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 uint32_t color_stop_to_pixel(const cairo_gradient_stop_t *stop)
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 @@ _cairo_gl_gradient_render (const cairo_gl_context_t *ctx,
}
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 @@ _cairo_gl_gradient_render (const cairo_gl_context_t *ctx,
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,16 +219,16 @@ _cairo_gl_gradient_equal (const void *key_a, const void *key_b)
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;
}
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 @@ _cairo_gl_gradient_create (cairo_gl_context_t *ctx,
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 @@ _cairo_gl_gradient_create (cairo_gl_context_t *ctx,
* 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 @@ _cairo_gl_gradient_destroy (cairo_gl_gradient_t *gradient)
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);
diff --git a/Build/source/libs/cairo/cairo-src/src/cairo-gl-info.c b/Build/source/libs/cairo/cairo-src/src/cairo-gl-info.c
index acefbb91059..26b7b45511d 100644
--- a/Build/source/libs/cairo/cairo-src/src/cairo-gl-info.c
+++ b/Build/source/libs/cairo/cairo-src/src/cairo-gl-info.c
@@ -65,8 +65,10 @@ _cairo_gl_get_flavor (void)
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 @@ _cairo_gl_get_vbo_size (void)
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);
diff --git a/Build/source/libs/cairo/cairo-src/src/cairo-gl-msaa-compositor.c b/Build/source/libs/cairo/cairo-src/src/cairo-gl-msaa-compositor.c
index 83e8eb2d160..7a83dd21942 100644
--- a/Build/source/libs/cairo/cairo-src/src/cairo-gl-msaa-compositor.c
+++ b/Build/source/libs/cairo/cairo-src/src/cairo-gl-msaa-compositor.c
@@ -224,8 +224,8 @@ _should_use_unbounded_surface (cairo_composite_rectangles_t *composite)
/* 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 @@ _prepare_unbounded_surface (cairo_gl_surface_t *dst)
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 @@ static cairo_bool_t
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 @@ can_use_msaa_compositor (cairo_gl_surface_t *surface,
/* 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 @@ _cairo_gl_msaa_compositor_mask_source_operator (const cairo_compositor_t *compos
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 @@ _cairo_gl_msaa_compositor_mask_source_operator (const cairo_compositor_t *compos
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 @@ _stroke_shaper_add_quad (void *closure,
}
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 @@ _prevent_overlapping_strokes (cairo_gl_context_t *ctx,
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 @@ query_surface_capabilities (cairo_gl_surface_t *surface)
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 @@ _cairo_gl_msaa_compositor_fill (const cairo_compositor_t *compositor,
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 @@ _cairo_gl_msaa_compositor_init (cairo_compositor_t *compositor,
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;
}
diff --git a/Build/source/libs/cairo/cairo-src/src/cairo-gl-operand.c b/Build/source/libs/cairo/cairo-src/src/cairo-gl-operand.c
index 1d1465a0be9..a754bde2f31 100644
--- a/Build/source/libs/cairo/cairo-src/src/cairo-gl-operand.c
+++ b/Build/source/libs/cairo/cairo-src/src/cairo-gl-operand.c
@@ -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 @@ _cairo_gl_subsurface_clone_operand_init (cairo_gl_operand_t *operand,
status = _cairo_gl_surface_resolve_multisampling (surface);
if (unlikely (status))
- return status;
+ return status;
attributes = &operand->texture.attributes;
@@ -336,7 +336,7 @@ fail:
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 @@ _cairo_gl_operand_translate (cairo_gl_operand_t *operand,
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 @@ _cairo_gl_operand_copy (cairo_gl_operand_t *dst,
break;
default:
case CAIRO_GL_OPERAND_COUNT:
- ASSERT_NOT_REACHED;
+ ASSERT_NOT_REACHED;
case CAIRO_GL_OPERAND_NONE:
- break;
+ break;
}
}
@@ -505,9 +505,9 @@ _cairo_gl_operand_destroy (cairo_gl_operand_t *operand)
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_gl_operand_destroy (cairo_gl_operand_t *operand)
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,25 +614,25 @@ _cairo_gl_operand_get_extend (cairo_gl_operand_t *operand)
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;
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_operand_bind_to_shader (cairo_gl_context_t *ctx,
_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 @@ _cairo_gl_operand_bind_to_shader (cairo_gl_context_t *ctx,
* 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_gl_operand_bind_to_shader (cairo_gl_context_t *ctx,
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 @@ _cairo_gl_operand_get_vertex_size (const cairo_gl_operand_t *operand)
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 @@ _cairo_gl_operand_emit (cairo_gl_operand_t *operand,
*(*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_matrix_transform_point (&src_attributes->matrix, &s, &t);
- *(*vb)++ = s;
- *(*vb)++ = t;
- }
- break;
+ 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;
}
}
diff --git a/Build/source/libs/cairo/cairo-src/src/cairo-gl-private.h b/Build/source/libs/cairo/cairo-src/src/cairo-gl-private.h
index cb915c8cf25..f02a58763e9 100644
--- a/Build/source/libs/cairo/cairo-src/src/cairo-gl-private.h
+++ b/Build/source/libs/cairo/cairo-src/src/cairo-gl-private.h
@@ -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 @@ struct _cairo_gl_surface {
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 @@ struct _cairo_gl_surface {
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_gl_composite_glyphs_with_clip (void *_dst,
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,
diff --git a/Build/source/libs/cairo/cairo-src/src/cairo-gl-shaders.c b/Build/source/libs/cairo/cairo-src/src/cairo-gl-shaders.c
index fe975d2d7c9..c43cf3b18d5 100644
--- a/Build/source/libs/cairo/cairo-src/src/cairo-gl-shaders.c
+++ b/Build/source/libs/cairo/cairo-src/src/cairo-gl-shaders.c
@@ -132,7 +132,7 @@ _cairo_gl_shader_cache_destroy (void *data)
_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 @@ _cairo_gl_context_init_shaders (cairo_gl_context_t *ctx)
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 @@ cairo_gl_operand_get_var_type (cairo_gl_operand_t *operand)
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 @@ cairo_gl_shader_def_coverage (cairo_output_stream_t *stream)
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 @@ _cairo_gl_shader_needs_border_fade (cairo_gl_operand_t *operand)
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 @@ cairo_gl_shader_emit_color (cairo_output_stream_t *stream,
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 @@ cairo_gl_shader_emit_color (cairo_output_stream_t *stream,
"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 @@ cairo_gl_shader_emit_color (cairo_output_stream_t *stream,
"}\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 @@ cairo_gl_shader_emit_color (cairo_output_stream_t *stream,
"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 @@ cairo_gl_shader_emit_color (cairo_output_stream_t *stream,
" 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 @@ cairo_gl_shader_emit_color (cairo_output_stream_t *stream,
" 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 @@ _cairo_gl_shader_emit_wrap (cairo_gl_context_t *ctx,
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_get_fragment_source (cairo_gl_context_t *ctx,
_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_gl_shader_get_fragment_source (cairo_gl_context_t *ctx,
}
_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_set_shader (cairo_gl_context_t *ctx,
cairo_gl_shader_t *shader)
{
if (ctx->current_shader == shader)
- return;
+ return;
if (shader)
ctx->dispatch.UseProgram (shader->program);
@@ -1007,11 +1012,11 @@ _cairo_gl_set_shader (cairo_gl_context_t *ctx,
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 @@ _cairo_gl_get_shader_by_type (cairo_gl_context_t *ctx,
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 @@ _cairo_gl_get_shader_by_type (cairo_gl_context_t *ctx,
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));
diff --git a/Build/source/libs/cairo/cairo-src/src/cairo-gl-source.c b/Build/source/libs/cairo/cairo-src/src/cairo-gl-source.c
index 12235295f40..7e0ee4a826f 100644
--- a/Build/source/libs/cairo/cairo-src/src/cairo-gl-source.c
+++ b/Build/source/libs/cairo/cairo-src/src/cairo-gl-source.c
@@ -69,14 +69,15 @@ _cairo_gl_pattern_to_source (cairo_surface_t *dst,
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));
_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,14 +97,15 @@ _cairo_gl_white_source (void)
{
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));
_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);
diff --git a/Build/source/libs/cairo/cairo-src/src/cairo-gl-spans-compositor.c b/Build/source/libs/cairo/cairo-src/src/cairo-gl-spans-compositor.c
index 4317ccd074a..0a4538a047c 100644
--- a/Build/source/libs/cairo/cairo-src/src/cairo-gl-spans-compositor.c
+++ b/Build/source/libs/cairo/cairo-src/src/cairo-gl-spans-compositor.c
@@ -139,27 +139,27 @@ _cairo_gl_unbounded_spans (void *abstract_renderer,
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 @@ _cairo_gl_clipped_spans (void *abstract_renderer,
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 @@ fill_boxes (void *_dst,
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,14 +341,14 @@ static cairo_int_status_t copy_boxes (void *_dst,
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);
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 @@ composite_boxes (void *_dst,
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 @@ composite_boxes (void *_dst,
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,17 +454,17 @@ _cairo_gl_span_renderer_init (cairo_abstract_span_renderer_t *_r,
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,
&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 @@ _cairo_gl_span_renderer_init (cairo_abstract_span_renderer_t *_r,
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 @@ _cairo_gl_span_renderer_init (cairo_abstract_span_renderer_t *_r,
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 @@ _cairo_gl_span_renderer_fini (cairo_abstract_span_renderer_t *_r,
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 @@ _cairo_gl_span_compositor_get (void)
//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;
diff --git a/Build/source/libs/cairo/cairo-src/src/cairo-gl-surface.c b/Build/source/libs/cairo/cairo-src/src/cairo-gl-surface.c
index cfccf4dfda5..12ea3ddc4b4 100644
--- a/Build/source/libs/cairo/cairo-src/src/cairo-gl-surface.c
+++ b/Build/source/libs/cairo/cairo-src/src/cairo-gl-surface.c
@@ -389,11 +389,13 @@ _cairo_gl_surface_init (cairo_device_t *device,
_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_create_scratch_for_texture (cairo_gl_context_t *ctx,
_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 @@ _cairo_gl_surface_create_scratch_for_caching (cairo_gl_context_t *ctx,
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_surface_clear (cairo_gl_surface_t *surface,
_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 @@ cairo_gl_surface_set_size (cairo_surface_t *abstract_surface,
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 @@ cairo_gl_surface_swapbuffers (cairo_surface_t *abstract_surface)
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 @@ cairo_gl_surface_swapbuffers (cairo_surface_t *abstract_surface)
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 @@ cairo_gl_surface_swapbuffers (cairo_surface_t *abstract_surface)
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_gl_surface_create_similar (void *abstract_surface,
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 @@ _cairo_gl_surface_create_similar (void *abstract_surface,
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 @@ _cairo_gl_surface_fill_alpha_channel (cairo_gl_surface_t *dst,
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,12 +870,54 @@ _cairo_gl_surface_draw_image (cairo_gl_surface_t *dst,
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);
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 @@ _cairo_gl_surface_draw_image (cairo_gl_surface_t *dst,
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 @@ _cairo_gl_surface_draw_image (cairo_gl_surface_t *dst,
* 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 @@ _cairo_gl_surface_draw_image (cairo_gl_surface_t *dst,
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 @@ _cairo_gl_surface_draw_image (cairo_gl_surface_t *dst,
dst_x, dst_y,
width, height);
}
+ if (ctx->gl_flavor == CAIRO_GL_FLAVOR_ES3)
+ dst->content_in_texture = TRUE;
} else {
- cairo_surface_t *tmp;
-
- 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;
+ cairo_surface_t *tmp;
+
+ 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;
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,17 +1051,22 @@ _cairo_gl_surface_draw_image (cairo_gl_surface_t *dst,
&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:
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,28 +1086,28 @@ _cairo_gl_surface_finish (void *abstract_surface)
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);
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 @@ _cairo_gl_surface_map_to_image (void *abstract_surface,
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 @@ _cairo_gl_surface_map_to_image (void *abstract_surface,
* 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 @@ _cairo_gl_surface_map_to_image (void *abstract_surface,
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 @@ _cairo_gl_surface_flush (void *abstract_surface, unsigned flags)
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,7 +1396,10 @@ _cairo_gl_surface_resolve_multisampling (cairo_gl_surface_t *surface)
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))
@@ -1328,10 +1409,20 @@ _cairo_gl_surface_resolve_multisampling (cairo_gl_surface_t *surface)
if (unlikely (status))
return status;
- ctx->current_target = surface;
+#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;
-#if CAIRO_HAS_GL_SURFACE
+#elif CAIRO_HAS_GL_SURFACE
+ ctx->current_target = 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 @@ _cairo_gl_surface_paint (void *surface,
{
/* 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 @@ _cairo_gl_surface_mask (void *surface,
}
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 @@ _cairo_gl_surface_stroke (void *surface,
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,
diff --git a/Build/source/libs/cairo/cairo-src/src/cairo-gl-traps-compositor.c b/Build/source/libs/cairo/cairo-src/src/cairo-gl-traps-compositor.c
index 125ed4eabcb..7938c5b20a5 100644
--- a/Build/source/libs/cairo/cairo-src/src/cairo-gl-traps-compositor.c
+++ b/Build/source/libs/cairo/cairo-src/src/cairo-gl-traps-compositor.c
@@ -137,13 +137,13 @@ fill_boxes (void *_dst,
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 @@ composite_boxes (void *_dst,
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 @@ composite_boxes (void *_dst,
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 @@ composite (void *_dst,
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 @@ composite (void *_dst,
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 @@ traps_to_operand (void *_dst,
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 @@ composite_traps (void *_dst,
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 @@ composite_traps (void *_dst,
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 @@ composite_tristrip (void *_dst,
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 @@ composite_tristrip (void *_dst,
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 @@ check_composite (const cairo_composite_rectangles_t *extents)
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 @@ _cairo_gl_traps_compositor_get (void)
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;
diff --git a/Build/source/libs/cairo/cairo-src/src/cairo-gl.h b/Build/source/libs/cairo/cairo-src/src/cairo-gl.h
index 9fd7608f5cf..7cd869c76b1 100644
--- a/Build/source/libs/cairo/cairo-src/src/cairo-gl.h
+++ b/Build/source/libs/cairo/cairo-src/src/cairo-gl.h
@@ -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
diff --git a/Build/source/libs/cairo/cairo-src/src/cairo-glx-context.c b/Build/source/libs/cairo/cairo-src/src/cairo-glx-context.c
index 3761b9079a4..66f5a0d1b45 100644
--- a/Build/source/libs/cairo/cairo-src/src/cairo-glx-context.c
+++ b/Build/source/libs/cairo/cairo-src/src/cairo-glx-context.c
@@ -310,7 +310,7 @@ cairo_gl_surface_create_for_window (cairo_device_t *device,
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))
diff --git a/Build/source/libs/cairo/cairo-src/src/cairo-gstate-private.h b/Build/source/libs/cairo/cairo-src/src/cairo-gstate-private.h
index b2ccc76d145..198c6699855 100644
--- a/Build/source/libs/cairo/cairo-src/src/cairo-gstate-private.h
+++ b/Build/source/libs/cairo/cairo-src/src/cairo-gstate-private.h
@@ -324,6 +324,15 @@ _cairo_gstate_show_surface (cairo_gstate_t *gstate,
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);
diff --git a/Build/source/libs/cairo/cairo-src/src/cairo-gstate.c b/Build/source/libs/cairo/cairo-src/src/cairo-gstate.c
index b4e988e96d8..ff0cb8be734 100644
--- a/Build/source/libs/cairo/cairo-src/src/cairo-gstate.c
+++ b/Build/source/libs/cairo/cairo-src/src/cairo-gstate.c
@@ -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_gstate_fini (cairo_gstate_t *gstate)
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 @@ _cairo_gstate_save (cairo_gstate_t **gstate, cairo_gstate_t **freelist)
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_gstate_in_stroke (cairo_gstate_t *gstate,
_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 @@ _cairo_gstate_copy_clip_rectangle_list (cairo_gstate_t *gstate)
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 @@ _cairo_gstate_transform_glyphs_to_backend (cairo_gstate_t *gstate,
*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
diff --git a/Build/source/libs/cairo/cairo-src/src/cairo-hash.c b/Build/source/libs/cairo/cairo-src/src/cairo-hash.c
index 928c74b8bd6..5a789906f2b 100644
--- a/Build/source/libs/cairo/cairo-src/src/cairo-hash.c
+++ b/Build/source/libs/cairo/cairo-src/src/cairo-hash.c
@@ -164,7 +164,7 @@ _cairo_hash_table_create (cairo_hash_keys_equal_func_t keys_equal)
{
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;
diff --git a/Build/source/libs/cairo/cairo-src/src/cairo-image-compositor.c b/Build/source/libs/cairo/cairo-src/src/cairo-image-compositor.c
index 48072f81bd0..bbf4cf2281d 100644
--- a/Build/source/libs/cairo/cairo-src/src/cairo-image-compositor.c
+++ b/Build/source/libs/cairo/cairo-src/src/cairo-image-compositor.c
@@ -821,6 +821,18 @@ get_glyph_cache (void)
}
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 @@ out_unlock:
}
#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 @@ check_composite (const cairo_composite_rectangles_t *extents)
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 @@ _cairo_image_traps_compositor_get (void)
#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 @@ _cairo_image_traps_compositor_get (void)
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 @@ _cairo_image_mask_compositor_get (void)
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 @@ typedef struct _cairo_image_span_renderer {
pixman_image_t *src, *mask;
union {
struct fill {
- int stride;
+ ptrdiff_t stride;
uint8_t *data;
uint32_t pixel;
} fill;
@@ -1594,7 +1617,7 @@ typedef struct _cairo_image_span_renderer {
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 @@ _fill16_spans (void *abstract_renderer, int y, int h,
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 @@ _fill16_spans (void *abstract_renderer, int y, int h,
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 @@ _fill32_spans (void *abstract_renderer, int y, int h,
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 @@ _fill32_spans (void *abstract_renderer, int y, int h,
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 @@ _fill_a8_lerp_opaque_spans (void *abstract_renderer, int y, int h,
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 @@ _fill_a8_lerp_opaque_spans (void *abstract_renderer, int y, int h,
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 @@ _fill_xrgb32_lerp_opaque_spans (void *abstract_renderer, int y, int h,
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 @@ _fill_xrgb32_lerp_opaque_spans (void *abstract_renderer, int y, int h,
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 @@ _fill_a8_lerp_spans (void *abstract_renderer, int y, int h,
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 @@ _fill_a8_lerp_spans (void *abstract_renderer, int y, int h,
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 @@ _fill_xrgb32_lerp_spans (void *abstract_renderer, int y, int h,
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 @@ _fill_xrgb32_lerp_spans (void *abstract_renderer, int y, int h,
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 @@ _blit_xrgb32_lerp_spans (void *abstract_renderer, int y, int h,
else
memcpy(d, s, len*4);
} else {
- while (len--) {
+ while (len-- > 0) {
*d = lerp8x4 (*s, a, *d);
s++, d++;
}
@@ -2430,7 +2453,7 @@ _blit_xrgb32_lerp_spans (void *abstract_renderer, int y, int h,
else
memcpy(d, s, len * 4);
} else {
- while (len--) {
+ while (len-- > 0) {
*d = lerp8x4 (*s, a, *d);
s++, d++;
}
@@ -2911,7 +2934,7 @@ inplace_renderer_init (cairo_image_span_renderer_t *r,
/* 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 @@ span_renderer_fini (cairo_abstract_span_renderer_t *_r,
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 @@ _cairo_image_spans_compositor_get (void)
//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;
diff --git a/Build/source/libs/cairo/cairo-src/src/cairo-image-source.c b/Build/source/libs/cairo/cairo-src/src/cairo-image-source.c
index 950053db2c1..0b50afcad32 100644
--- a/Build/source/libs/cairo/cairo-src/src/cairo-image-source.c
+++ b/Build/source/libs/cairo/cairo-src/src/cairo-image-source.c
@@ -872,7 +872,7 @@ create_separable_convolution (int *n_values,
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 @@ attach_proxy (cairo_surface_t *source,
{
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 @@ _pixman_image_for_recording (cairo_image_surface_t *dst,
{
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 @@ _pixman_image_for_recording (cairo_image_surface_t *dst,
*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;
-
- 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;
-
- _cairo_matrix_transform_bounding_box (&matrix,
- &x1, &y1, &x2, &y2, NULL);
+ if (! _cairo_matrix_is_identity (&pattern->base.matrix)) {
+ double x1, y1, x2, y2;
- limit.x = floor (x1);
- limit.y = floor (y1);
- limit.width = ceil (x2) - limit.x;
- limit.height = ceil (y2) - limit.y;
- }
+ 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;
+
+ _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;
+ sx = (double)src_limit.width / limit.width;
+ sy = (double)src_limit.height / limit.height;
}
tx = limit.x;
ty = limit.y;
@@ -1183,7 +1189,9 @@ _pixman_image_for_recording (cairo_image_surface_t *dst,
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 @@ done:
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 @@ _pixman_image_for_surface (cairo_image_surface_t *dst,
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 @@ _pixman_image_for_raster (cairo_image_surface_t *dst,
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 @@ _cairo_image_source_create_for_pattern (cairo_surface_t *dst,
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_image_source_create_for_pattern (cairo_surface_t *dst,
_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);
diff --git a/Build/source/libs/cairo/cairo-src/src/cairo-image-surface-private.h b/Build/source/libs/cairo/cairo-src/src/cairo-image-surface-private.h
index 8ca694c5e3e..2b7921133f7 100644
--- a/Build/source/libs/cairo/cairo-src/src/cairo-image-surface-private.h
+++ b/Build/source/libs/cairo/cairo-src/src/cairo-image-surface-private.h
@@ -40,6 +40,7 @@
#include "cairo-surface-private.h"
+#include <stddef.h>
#include <pixman.h>
CAIRO_BEGIN_DECLS
@@ -71,7 +72,7 @@ struct _cairo_image_surface {
int width;
int height;
- int stride;
+ ptrdiff_t stride;
int depth;
unsigned owns_data : 1;
diff --git a/Build/source/libs/cairo/cairo-src/src/cairo-image-surface.c b/Build/source/libs/cairo/cairo-src/src/cairo-image-surface.c
index 1fd563d1c34..2ee1cad42cf 100644
--- a/Build/source/libs/cairo/cairo-src/src/cairo-image-surface.c
+++ b/Build/source/libs/cairo/cairo-src/src/cairo-image-surface.c
@@ -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,14 +182,15 @@ _cairo_image_surface_create_for_pixman_image (pixman_image_t *pixman_image,
{
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));
_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 @@ _cairo_image_surface_create_with_pixman_format (unsigned char *data,
* @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,79 +1154,87 @@ cleanup:
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;
-
- if (image->transparency != CAIRO_IMAGE_UNKNOWN)
- return image->transparency;
+ cairo_image_transparency_t 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);
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);
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)
{
- int x, y;
+ if (_cairo_surface_is_snapshot (&image->base)) {
+ if (image->transparency == CAIRO_IMAGE_UNKNOWN)
+ image->transparency = _cairo_image_compute_transparency (image);
- if (image->color != CAIRO_IMAGE_UNKNOWN_COLOR)
- return image->color;
+ 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->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 @@ _cairo_image_analyze_color (cairo_image_surface_t *image)
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 @@ _cairo_image_analyze_color (cairo_image_surface_t *image)
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 *
diff --git a/Build/source/libs/cairo/cairo-src/src/cairo-line.c b/Build/source/libs/cairo/cairo-src/src/cairo-line.c
index cb13927bdce..dc00a9cb19d 100644
--- a/Build/source/libs/cairo/cairo-src/src/cairo-line.c
+++ b/Build/source/libs/cairo/cairo-src/src/cairo-line.c
@@ -110,9 +110,9 @@ lines_compare_x_for_y_general (const cairo_line_t *a,
* 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 @@ lines_compare_x_for_y (const cairo_line_t *a,
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;
diff --git a/Build/source/libs/cairo/cairo-src/src/cairo-lzw.c b/Build/source/libs/cairo/cairo-src/src/cairo-lzw.c
index de7f9998376..f27b3c33842 100644
--- a/Build/source/libs/cairo/cairo-src/src/cairo-lzw.c
+++ b/Build/source/libs/cairo/cairo-src/src/cairo-lzw.c
@@ -73,7 +73,7 @@ _lzw_buf_init (lzw_buf_t *buf, int size)
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);
diff --git a/Build/source/libs/cairo/cairo-src/src/cairo-malloc-private.h b/Build/source/libs/cairo/cairo-src/src/cairo-malloc-private.h
index 1e2c67f8d9a..570f7cb0ee7 100644
--- a/Build/source/libs/cairo/cairo-src/src/cairo-malloc-private.h
+++ b/Build/source/libs/cairo/cairo-src/src/cairo-malloc-private.h
@@ -60,7 +60,7 @@
**/
#define _cairo_malloc(size) \
- ((size) ? malloc((unsigned) (size)) : NULL)
+ ((size) > 0 ? malloc((unsigned) (size)) : NULL)
/**
* _cairo_malloc_ab:
diff --git a/Build/source/libs/cairo/cairo-src/src/cairo-matrix.c b/Build/source/libs/cairo/cairo-src/src/cairo-matrix.c
index ae498f5151a..f3cf684c9d6 100644
--- a/Build/source/libs/cairo/cairo-src/src/cairo-matrix.c
+++ b/Build/source/libs/cairo/cairo-src/src/cairo-matrix.c
@@ -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
diff --git a/Build/source/libs/cairo/cairo-src/src/cairo-mempool.c b/Build/source/libs/cairo/cairo-src/src/cairo-mempool.c
index 751ede320f3..ce40ce521ff 100644
--- a/Build/source/libs/cairo/cairo-src/src/cairo-mempool.c
+++ b/Build/source/libs/cairo/cairo-src/src/cairo-mempool.c
@@ -316,7 +316,7 @@ _cairo_mempool_init (cairo_mempool_t *pool,
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);
diff --git a/Build/source/libs/cairo/cairo-src/src/cairo-mesh-pattern-rasterizer.c b/Build/source/libs/cairo/cairo-src/src/cairo-mesh-pattern-rasterizer.c
index 1b63ca8a660..e7f0db666ae 100644
--- a/Build/source/libs/cairo/cairo-src/src/cairo-mesh-pattern-rasterizer.c
+++ b/Build/source/libs/cairo/cairo-src/src/cairo-mesh-pattern-rasterizer.c
@@ -470,7 +470,7 @@ draw_pixel (unsigned char *data, int width, int height, int stride,
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);
}
}
diff --git a/Build/source/libs/cairo/cairo-src/src/cairo-misc.c b/Build/source/libs/cairo/cairo-src/src/cairo-misc.c
index 3c7c959862d..6e63bc7e6ea 100644
--- a/Build/source/libs/cairo/cairo-src/src/cairo-misc.c
+++ b/Build/source/libs/cairo/cairo-src/src/cairo-misc.c
@@ -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 @@ COMPILE_TIME_ASSERT (CAIRO_INT_STATUS_LAST_STATUS <= 127);
* @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 @@ cairo_status_to_string (cairo_status_t status)
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 @@ _cairo_half_from_float (float f)
# 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 @@ cairo_get_locale_decimal_point (void)
#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 @@ typedef struct _cairo_intern_string {
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 @@ _cairo_intern_string (const char **str_inout, int len)
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 @@ _cairo_intern_string (const char **str_inout, int len)
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;
diff --git a/Build/source/libs/cairo/cairo-src/src/cairo-mono-scan-converter.c b/Build/source/libs/cairo/cairo-src/src/cairo-mono-scan-converter.c
index 2a9546cf82a..891f435c9eb 100644
--- a/Build/source/libs/cairo/cairo-src/src/cairo-mono-scan-converter.c
+++ b/Build/source/libs/cairo/cairo-src/src/cairo-mono-scan-converter.c
@@ -587,7 +587,7 @@ _cairo_mono_scan_converter_create (int xmin,
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;
diff --git a/Build/source/libs/cairo/cairo-src/src/cairo-os2-surface.c b/Build/source/libs/cairo/cairo-src/src/cairo-os2-surface.c
index 1ab50f97798..84f08c8077f 100644
--- a/Build/source/libs/cairo/cairo-src/src/cairo-os2-surface.c
+++ b/Build/source/libs/cairo/cairo-src/src/cairo-os2-surface.c
@@ -198,7 +198,7 @@ void *_buffer_alloc (size_t a, size_t b, const unsigned int size)
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 @@ cairo_os2_surface_create (HPS hps_client_window,
}
/* 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_os2_surface_create (HPS hps_client_window,
_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;
diff --git a/Build/source/libs/cairo/cairo-src/src/cairo-output-stream.c b/Build/source/libs/cairo/cairo-src/src/cairo-output-stream.c
index 05d9a2a005d..935fa44c332 100644
--- a/Build/source/libs/cairo/cairo-src/src/cairo-output-stream.c
+++ b/Build/source/libs/cairo/cairo-src/src/cairo-output-stream.c
@@ -147,7 +147,7 @@ _cairo_output_stream_create (cairo_write_func_t write_func,
{
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 @@ _cairo_output_stream_create_in_error (cairo_status_t status)
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 @@ _cairo_output_stream_write_hex_string (cairo_output_stream_t *stream,
/* Format a double in a locale independent way and trim trailing
* zeros. Based on code from Alex Larson <alexl@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 @@ _cairo_dtostr (char *buffer, size_t size, double d, cairo_bool_t limited_precisi
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 @@ _cairo_output_stream_create_for_file (FILE *file)
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 @@ _cairo_output_stream_create_for_filename (const char *filename)
{
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 @@ _cairo_output_stream_create_for_filename (const char *filename)
}
}
- 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 @@ _cairo_memory_stream_create (void)
{
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 @@ _cairo_memory_stream_destroy (cairo_output_stream_t *abstract_stream,
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_null_stream_create (void)
{
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;
diff --git a/Build/source/libs/cairo/cairo-src/src/cairo-paginated-private.h b/Build/source/libs/cairo/cairo-src/src/cairo-paginated-private.h
index b827faba0ef..b85a5db6b76 100644
--- a/Build/source/libs/cairo/cairo-src/src/cairo-paginated-private.h
+++ b/Build/source/libs/cairo/cairo-src/src/cairo-paginated-private.h
@@ -56,7 +56,7 @@ struct _cairo_paginated_surface_backend {
* 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 @@ struct _cairo_paginated_surface_backend {
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
diff --git a/Build/source/libs/cairo/cairo-src/src/cairo-paginated-surface.c b/Build/source/libs/cairo/cairo-src/src/cairo-paginated-surface.c
index 68e4e0e34fd..fc16f790be8 100644
--- a/Build/source/libs/cairo/cairo-src/src/cairo-paginated-surface.c
+++ b/Build/source/libs/cairo/cairo-src/src/cairo-paginated-surface.c
@@ -98,7 +98,7 @@ _cairo_paginated_surface_create (cairo_surface_t *target,
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_paginated_surface_create (cairo_surface_t *target,
_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 @@ _cairo_paginated_surface_release_source_image (void *abstract_surface,
}
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 @@ _paint_page (cairo_paginated_surface_t *surface)
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 @@ _paint_page (cairo_paginated_surface_t *surface)
}
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 @@ _paint_page (cairo_paginated_surface_t *surface)
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 @@ _paint_page (cairo_paginated_surface_t *surface)
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 @@ _paint_page (cairo_paginated_surface_t *surface)
}
}
+ 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 @@ _cairo_paginated_surface_get_supported_mime_types (void *abstract_surface)
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 @@ static const cairo_surface_backend_t cairo_paginated_surface_backend = {
_cairo_paginated_surface_has_show_text_glyphs,
_cairo_paginated_surface_show_text_glyphs,
_cairo_paginated_surface_get_supported_mime_types,
+ _cairo_paginated_surface_tag,
};
diff --git a/Build/source/libs/cairo/cairo-src/src/cairo-path-bounds.c b/Build/source/libs/cairo/cairo-src/src/cairo-path-bounds.c
index 9c7222426d3..ac85f27bee3 100644
--- a/Build/source/libs/cairo/cairo-src/src/cairo-path-bounds.c
+++ b/Build/source/libs/cairo/cairo-src/src/cairo-path-bounds.c
@@ -154,6 +154,7 @@ void
_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,6 +162,17 @@ _cairo_path_fixed_approximate_stroke_extents (const cairo_path_fixed_t *path,
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);
@@ -185,6 +197,17 @@ _cairo_path_fixed_stroke_extents (const cairo_path_fixed_t *path,
{
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,
diff --git a/Build/source/libs/cairo/cairo-src/src/cairo-path-fixed.c b/Build/source/libs/cairo/cairo-src/src/cairo-path-fixed.c
index 4bbf496f075..9e9166cbdaa 100644
--- a/Build/source/libs/cairo/cairo-src/src/cairo-path-fixed.c
+++ b/Build/source/libs/cairo/cairo-src/src/cairo-path-fixed.c
@@ -325,7 +325,7 @@ _cairo_path_fixed_create (void)
{
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_fixed_fini (cairo_path_fixed_t *path)
_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
diff --git a/Build/source/libs/cairo/cairo-src/src/cairo-path.c b/Build/source/libs/cairo/cairo-src/src/cairo-path.c
index 43cd175a3c5..566e86f5a8e 100644
--- a/Build/source/libs/cairo/cairo-src/src/cairo-path.c
+++ b/Build/source/libs/cairo/cairo-src/src/cairo-path.c
@@ -294,7 +294,7 @@ _cairo_path_create_in_error (cairo_status_t status)
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_create_internal (cairo_path_fixed_t *path_fixed,
{
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;
diff --git a/Build/source/libs/cairo/cairo-src/src/cairo-pattern-private.h b/Build/source/libs/cairo/cairo-src/src/cairo-pattern-private.h
index be8ab9fc239..26d584e686a 100644
--- a/Build/source/libs/cairo/cairo-src/src/cairo-pattern-private.h
+++ b/Build/source/libs/cairo/cairo-src/src/cairo-pattern-private.h
@@ -256,6 +256,11 @@ _cairo_gradient_pattern_is_solid (const cairo_gradient_pattern_t *gradient,
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_pattern_sampled_area (const cairo_pattern_t *pattern,
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,
diff --git a/Build/source/libs/cairo/cairo-src/src/cairo-pattern.c b/Build/source/libs/cairo/cairo-src/src/cairo-pattern.c
index f0b879836df..fde044a4d1e 100644
--- a/Build/source/libs/cairo/cairo-src/src/cairo-pattern.c
+++ b/Build/source/libs/cairo/cairo-src/src/cairo-pattern.c
@@ -357,6 +357,7 @@ _cairo_pattern_init_copy (cairo_pattern_t *pattern,
/* 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_pattern_init_static_copy (cairo_pattern_t *pattern,
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 @@ _cairo_pattern_fini (cairo_pattern_t *pattern)
#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 @@ _cairo_pattern_create_copy (cairo_pattern_t **pattern_out,
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 @@ _cairo_pattern_create_solid (const cairo_color_t *color)
_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 @@ cairo_pattern_create_for_surface (cairo_surface_t *surface)
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 @@ cairo_pattern_create_linear (double x0, double y0, double x1, double y1)
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 @@ cairo_pattern_create_radial (double cx0, double cy0, double radius0,
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 @@ cairo_pattern_create_mesh (void)
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 @@ cairo_pattern_create_mesh (void)
* @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 @@ slim_hidden_def (cairo_pattern_reference);
* 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 @@ _cairo_gradient_pattern_is_solid (const cairo_gradient_pattern_t *gradient,
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,13 +3577,17 @@ _cairo_pattern_sampled_area (const cairo_pattern_t *pattern,
* 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.
**/
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 @@ _cairo_pattern_get_extents (const cairo_pattern_t *pattern,
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 @@ _cairo_pattern_get_extents (const cairo_pattern_t *pattern,
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_ink_extents (const cairo_pattern_t *pattern,
}
}
- _cairo_pattern_get_extents (pattern, extents);
+ _cairo_pattern_get_extents (pattern, extents, TRUE);
return CAIRO_STATUS_SUCCESS;
}
@@ -4417,7 +4480,7 @@ cairo_mesh_pattern_get_path (cairo_pattern_t *pattern,
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 @@ static void
_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
diff --git a/Build/source/libs/cairo/cairo-src/src/cairo-pdf-interchange.c b/Build/source/libs/cairo/cairo-src/src/cairo-pdf-interchange.c
new file mode 100644
index 00000000000..7d8981b0927
--- /dev/null
+++ b/Build/source/libs/cairo/cairo-src/src/cairo-pdf-interchange.c
@@ -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@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;
+}
diff --git a/Build/source/libs/cairo/cairo-src/src/cairo-pdf-operators-private.h b/Build/source/libs/cairo/cairo-src/src/cairo-pdf-operators-private.h
index 4314a042e81..ed8be7f96e0 100644
--- a/Build/source/libs/cairo/cairo-src/src/cairo-pdf-operators-private.h
+++ b/Build/source/libs/cairo/cairo-src/src/cairo-pdf-operators-private.h
@@ -173,4 +173,12 @@ _cairo_pdf_operators_show_text_glyphs (cairo_pdf_operators_t *pdf_operators,
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 */
diff --git a/Build/source/libs/cairo/cairo-src/src/cairo-pdf-operators.c b/Build/source/libs/cairo/cairo-src/src/cairo-pdf-operators.c
index c509ad00ee1..491ef8ca22f 100644
--- a/Build/source/libs/cairo/cairo-src/src/cairo-pdf-operators.c
+++ b/Build/source/libs/cairo/cairo-src/src/cairo-pdf-operators.c
@@ -140,7 +140,7 @@ _cairo_pdf_operators_flush (cairo_pdf_operators_t *pdf_operators)
* 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 @@ _word_wrap_stream_create (cairo_output_stream_t *output, cairo_bool_t ps, int ma
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_pdf_operators_show_text_glyphs (cairo_pdf_operators_t *pdf_operators,
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 @@ _cairo_pdf_operators_show_text_glyphs (cairo_pdf_operators_t *pdf_operators,
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 */
diff --git a/Build/source/libs/cairo/cairo-src/src/cairo-pdf-shading.c b/Build/source/libs/cairo/cairo-src/src/cairo-pdf-shading.c
index 646e2cd4902..b114b3104ba 100644
--- a/Build/source/libs/cairo/cairo-src/src/cairo-pdf-shading.c
+++ b/Build/source/libs/cairo/cairo-src/src/cairo-pdf-shading.c
@@ -170,7 +170,7 @@ _cairo_pdf_shading_generate_data (cairo_pdf_shading_t *shading,
* 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);
diff --git a/Build/source/libs/cairo/cairo-src/src/cairo-pdf-surface-private.h b/Build/source/libs/cairo/cairo-src/src/cairo-pdf-surface-private.h
index 618ca4ede9f..3793332ce8c 100644
--- a/Build/source/libs/cairo/cairo-src/src/cairo-pdf-surface-private.h
+++ b/Build/source/libs/cairo/cairo-src/src/cairo-pdf-surface-private.h
@@ -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 @@ typedef struct _cairo_pdf_source_surface_entry {
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 @@ typedef struct _cairo_pdf_pattern {
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 @@ typedef struct _cairo_pdf_jbig2_global {
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 @@ struct _cairo_pdf_surface {
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,16 +266,19 @@ struct _cairo_pdf_surface {
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;
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 @@ struct _cairo_pdf_surface {
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 */
diff --git a/Build/source/libs/cairo/cairo-src/src/cairo-pdf-surface.c b/Build/source/libs/cairo/cairo-src/src/cairo-pdf-surface.c
index fd7dc7d5606..7eb61aa1e05 100644
--- a/Build/source/libs/cairo/cairo-src/src/cairo-pdf-surface.c
+++ b/Build/source/libs/cairo/cairo-src/src/cairo-pdf-surface.c
@@ -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,19 +124,62 @@
* 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
* (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 @@ static const char *_cairo_pdf_supported_mime_types[] =
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 @@ typedef struct _cairo_pdf_alpha_linear_function {
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,21 +268,28 @@ static cairo_int_status_t
_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
_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
_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 @@ _cairo_pdf_source_surface_equal (const void *key_a, const void *key_b);
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 @@ _cairo_pdf_surface_new_object (cairo_pdf_surface_t *surface)
return resource;
}
-static void
+void
_cairo_pdf_surface_update_object (cairo_pdf_surface_t *surface,
cairo_pdf_resource_t resource)
{
@@ -300,9 +339,10 @@ _cairo_pdf_surface_set_size_internal (cairo_pdf_surface_t *surface,
{
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_create_for_stream_internal (cairo_output_stream_t *output,
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_pdf_surface_create_for_stream_internal (cairo_output_stream_t *output,
_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_pdf_surface_create_for_stream_internal (cairo_output_stream_t *output,
_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 @@ _cairo_pdf_surface_create_for_stream_internal (cairo_output_stream_t *output,
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 @@ _cairo_pdf_surface_create_for_stream_internal (cairo_output_stream_t *output,
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 @@ cairo_pdf_surface_set_size (cairo_surface_t *surface,
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_pdf_surface_clear (cairo_pdf_surface_t *surface)
}
_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 @@ _cairo_pdf_surface_create_smask_group (cairo_pdf_surface_t *surface,
group->extents.width = surface->width;
group->extents.height = surface->height;
}
- group->extents = *extents;
return group;
}
@@ -1196,186 +1406,105 @@ _cairo_pdf_surface_release_source_image_from_pattern (cairo_pdf_surface_t
}
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)
-{
- cairo_surface_get_mime_data (source, CAIRO_MIME_TYPE_JBIG2,
- mime_data, mime_data_length);
- if (*mime_data == NULL)
- return CAIRO_INT_STATUS_UNSUPPORTED;
-
- return _cairo_image_info_get_jbig2_info (info, *mime_data, *mime_data_length);
-}
-
-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;
-
- 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)
+_get_source_surface_extents (cairo_surface_t *source,
+ cairo_rectangle_int_t *extents,
+ cairo_bool_t *bounded,
+ cairo_bool_t *subsurface)
{
cairo_int_status_t status;
- cairo_image_info_t info;
- const unsigned char *mime_data;
- unsigned long mime_data_length;
+ *bounded = TRUE;
+ *subsurface = FALSE;
if (source->type == CAIRO_SURFACE_TYPE_RECORDING) {
+ cairo_surface_t *free_me = NULL;
+
+ if (_cairo_surface_is_snapshot (source))
+ free_me = source = _cairo_surface_snapshot_get_target (source);
+
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;
- }
-
- 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;
+ cairo_surface_destroy (free_me);
+ } else {
+ *bounded = _cairo_surface_get_extents (source, extents);
}
- 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 @@ _cairo_pdf_surface_add_source_surface (cairo_pdf_surface_t *surface,
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,12 +1529,27 @@ _cairo_pdf_surface_add_source_surface (cairo_pdf_surface_t *surface,
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;
@@ -1415,61 +1559,76 @@ _cairo_pdf_surface_add_source_surface (cairo_pdf_surface_t *surface,
_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;
- status = CAIRO_STATUS_SUCCESS;
- } else {
- status = _get_source_surface_size (source_surface,
- width,
- height,
- source_extents);
- if (unlikely(status))
- goto release_source;
+ if (pdf_source)
+ *pdf_source = surface_entry;
- 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 (source_pattern && source_pattern->extend != CAIRO_EXTEND_NONE)
+ _cairo_unbounded_rectangle_init (&op_extents);
- 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;
- }
+ _cairo_rectangle_intersect (&op_extents, &surface_entry->extents);
+ _cairo_rectangle_union (&surface_entry->required_extents, &op_extents);
+ status = CAIRO_STATUS_SUCCESS;
}
-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)
+ 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;
+ }
- surface_entry = malloc (sizeof (cairo_pdf_source_surface_entry_t));
+ 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;
+ }
+
+ 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 @@ release_source:
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,7 +1686,11 @@ fail2:
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 @@ _cairo_pdf_surface_add_pdf_pattern_or_shading (cairo_pdf_surface_t *surface,
*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 @@ _cairo_pdf_surface_add_pdf_pattern_or_shading (cairo_pdf_surface_t *surface,
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 @@ _cairo_pdf_surface_open_stream (cairo_pdf_surface_t *surface,
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 @@ _cairo_pdf_surface_open_content_stream (cairo_pdf_surface_t *surface,
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 @@ _cairo_pdf_surface_open_content_stream (cairo_pdf_surface_t *surface,
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,10 +2204,16 @@ _cairo_pdf_surface_finish (void *abstract_surface)
{
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)
@@ -2032,9 +2221,9 @@ _cairo_pdf_surface_finish (void *abstract_surface)
_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 @@ _cairo_pdf_surface_finish (void *abstract_surface)
">>\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 @@ _cairo_pdf_surface_finish (void *abstract_surface)
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_pdf_surface_finish (void *abstract_surface)
_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_pdf_surface_finish (void *abstract_surface)
_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,18 +2310,26 @@ _cairo_pdf_surface_finish (void *abstract_surface)
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
_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,6 +2353,15 @@ _cairo_pdf_surface_start_page (void *abstract_surface)
}
_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_pdf_surface_has_fallback_images (void *abstract_surface,
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,22 +2393,47 @@ _cairo_pdf_surface_supports_fine_grained_fallbacks (void *abstract_surface)
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;
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 @@ _cairo_pdf_surface_add_padded_image_surface (cairo_pdf_surface_t *surfa
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 @@ _cairo_pdf_surface_lookup_jbig2_global (cairo_pdf_surface_t *surface,
}
}
- 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 @@ _cairo_pdf_surface_lookup_jbig2_global (cairo_pdf_surface_t *surface,
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 @@ _cairo_pdf_surface_emit_jbig2_image (cairo_pdf_surface_t *surface,
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 @@ _cairo_pdf_surface_emit_jbig2_image (cairo_pdf_surface_t *surface,
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 @@ _cairo_pdf_surface_emit_jpx_image (cairo_pdf_surface_t *surface,
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 @@ _cairo_pdf_surface_emit_jpx_image (cairo_pdf_surface_t *surface,
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 @@ _cairo_pdf_surface_emit_jpeg_image (cairo_pdf_surface_t *surface,
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,45 +3189,113 @@ _cairo_pdf_surface_emit_jpeg_image (cairo_pdf_surface_t *surface,
}
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];
+
+ 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;
- 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_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_jpx_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;
- status = _cairo_pdf_surface_emit_jpeg_image (surface, source->surface, source->hash_entry);
- if (status != CAIRO_INT_STATUS_UNSUPPORTED)
- return 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);
-
- 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);
+ _cairo_output_stream_write (surface->output, ccitt_data, ccitt_data_len);
+ status = _cairo_pdf_surface_close_stream (surface);
return status;
}
@@ -2989,50 +3304,58 @@ static cairo_int_status_t
_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;
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;
}
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 @@ _cairo_pdf_surface_emit_recording_surface (cairo_pdf_surface_t *surface,
*/
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 @@ _cairo_pdf_surface_emit_recording_surface (cairo_pdf_surface_t *surface,
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,25 +3410,118 @@ _cairo_pdf_surface_emit_recording_surface (cairo_pdf_surface_t *surface,
_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);
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;
+
+ /* 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;
+ }
- return _cairo_pdf_surface_emit_image_surface (surface, src_surface);
+ 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,51 +3530,54 @@ _cairo_pdf_surface_emit_surface_pattern (cairo_pdf_surface_t *surface,
{
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,
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 @@ _cairo_pdf_surface_emit_surface_pattern (cairo_pdf_surface_t *surface,
* 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 @@ _cairo_pdf_surface_emit_surface_pattern (cairo_pdf_surface_t *surface,
* 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_pdf_surface_emit_surface_pattern (cairo_pdf_surface_t *surface,
/* 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);
+
+ 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_height, &pattern_extents, &bbox);
+ _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 @@ _cairo_pdf_surface_emit_surface_pattern (cairo_pdf_surface_t *surface,
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 @@ cairo_pdf_surface_emit_transparency_group (cairo_pdf_surface_t *surface,
/* 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 @@ cairo_pdf_surface_emit_transparency_group (cairo_pdf_surface_t *surface,
* 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_pdf_surface_emit_gradient (cairo_pdf_surface_t *surface,
cairo_circle_double_t start, end;
double domain[2];
cairo_int_status_t status;
+ cairo_matrix_t mat;
assert (pattern->n_stops != 0);
@@ -3927,7 +4383,13 @@ _cairo_pdf_surface_emit_gradient (cairo_pdf_surface_t *surface,
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,13 +4521,19 @@ _cairo_pdf_surface_emit_mesh_pattern (cairo_pdf_surface_t *surface,
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);
/* 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))
@@ -4197,15 +4665,8 @@ _cairo_pdf_surface_emit_mesh_pattern (cairo_pdf_surface_t *surface,
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 @@ _cairo_pdf_surface_emit_pattern (cairo_pdf_surface_t *surface, cairo_pdf_pattern
break;
}
- _cairo_pdf_surface_set_size_internal (surface,
- old_width,
- old_height);
-
return status;
}
@@ -4244,17 +4701,16 @@ _cairo_pdf_surface_paint_surface_pattern (cairo_pdf_surface_t *surface,
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 @@ _cairo_pdf_surface_paint_surface_pattern (cairo_pdf_surface_t *surface,
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 @@ _cairo_pdf_surface_paint_surface_pattern (cairo_pdf_surface_t *surface,
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 @@ _cairo_pdf_surface_paint_surface_pattern (cairo_pdf_surface_t *surface,
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,34 +4776,35 @@ _cairo_pdf_surface_paint_surface_pattern (cairo_pdf_surface_t *surface,
_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;
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
_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 @@ _cairo_pdf_surface_paint_gradient (cairo_pdf_surface_t *surface,
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_pdf_surface_paint_pattern (cairo_pdf_surface_t *surface,
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 @@ _cairo_pdf_surface_paint_pattern (cairo_pdf_surface_t *surface,
op,
source,
extents,
+ alpha,
NULL,
mask);
case CAIRO_PATTERN_TYPE_LINEAR:
@@ -4414,7 +4880,8 @@ _cairo_pdf_surface_paint_pattern (cairo_pdf_surface_t *surface,
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_show_page (void *abstract_surface)
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_get_extents (void *abstract_surface,
{
cairo_pdf_surface_t *surface = abstract_surface;
- rectangle->x = 0;
- rectangle->y = 0;
-
- /* 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);
+ if (surface->surface_bounded)
+ *rectangle = surface->surface_extents;
- return TRUE;
+ return surface->surface_bounded;
}
static void
@@ -4639,28 +5113,6 @@ _cairo_pdf_surface_get_font_options (void *abstract_surface,
_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 @@ _cairo_pdf_surface_write_pages (cairo_pdf_surface_t *surface)
"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 @@ _utf8_to_pdf_string (const char *utf8, char **str_out)
}
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 @@ _utf8_to_pdf_string (const char *utf8, char **str_out)
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 @@ _cairo_pdf_surface_emit_cff_font (cairo_pdf_surface_t *surface,
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 @@ _cairo_pdf_surface_emit_truetype_font_subset (cairo_pdf_surface_t *surface,
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,16 +6307,16 @@ _cairo_pdf_surface_emit_type3_font_subset (cairo_pdf_surface_t *surface,
"<< /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"
" /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_pdf_surface_write_catalog (cairo_pdf_surface_t *surface)
_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_pdf_surface_write_mask_group (cairo_pdf_surface_t *surface,
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_pdf_surface_write_mask_group (cairo_pdf_surface_t *surface,
CAIRO_OPERATOR_OVER,
group->mask,
&group->extents,
- FALSE);
+ 1.0, /* alpha */
+ FALSE); /* mask */
if (unlikely (status))
return status;
@@ -6124,7 +6607,8 @@ _cairo_pdf_surface_write_mask_group (cairo_pdf_surface_t *surface,
CAIRO_OPERATOR_OVER,
group->source,
&group->extents,
- FALSE);
+ 1.0, /* alpha */
+ FALSE); /* mask */
if (unlikely (status))
return status;
@@ -6224,14 +6708,20 @@ _cairo_pdf_surface_write_smask_group (cairo_pdf_surface_t *surface,
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 @@ _cairo_pdf_surface_write_smask_group (cairo_pdf_surface_t *surface,
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 @@ _cairo_pdf_surface_write_smask_group (cairo_pdf_surface_t *surface,
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 @@ _cairo_pdf_surface_write_patterns_and_smask_groups (cairo_pdf_surface_t *surface
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 @@ _cairo_pdf_surface_write_patterns_and_smask_groups (cairo_pdf_surface_t *surface
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,9 +6855,14 @@ _cairo_pdf_surface_write_patterns_and_smask_groups (cairo_pdf_surface_t *surface
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) {
@@ -6362,7 +6873,7 @@ _cairo_pdf_surface_write_page (cairo_pdf_surface_t *surface)
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 @@ _cairo_pdf_surface_write_page (cairo_pdf_surface_t *surface)
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,21 +6941,45 @@ _cairo_pdf_surface_write_page (cairo_pdf_surface_t *surface)
" /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,
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);
+ }
+
+ 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");
+ }
- status = _cairo_pdf_surface_write_patterns_and_smask_groups (surface);
+ 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 @@ _cairo_pdf_surface_write_page (cairo_pdf_surface_t *surface)
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 @@ _cairo_pdf_surface_start_fallback (cairo_pdf_surface_t *surface)
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_pdf_surface_emit_combined_smask (cairo_pdf_surface_t *surface,
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 @@ _cairo_pdf_surface_emit_combined_smask (cairo_pdf_surface_t *surface,
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 @@ _cairo_pdf_surface_emit_combined_smask (cairo_pdf_surface_t *surface,
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_pdf_surface_emit_combined_smask (cairo_pdf_surface_t *surface,
_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 @@ _cairo_pdf_surface_emit_stencil_mask (cairo_pdf_surface_t *surface,
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 @@ _cairo_pdf_surface_paint (void *abstract_surface,
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 @@ _cairo_pdf_surface_paint (void *abstract_surface,
op,
source,
&extents.bounded,
- FALSE);
+ 1.0, /* alpha */
+ FALSE); /* mask */
if (unlikely (status))
goto cleanup;
@@ -7041,8 +7593,11 @@ _cairo_pdf_surface_paint (void *abstract_surface,
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_pdf_surface_mask (void *abstract_surface,
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 @@ _cairo_pdf_surface_mask (void *abstract_surface,
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 @@ _cairo_pdf_surface_mask (void *abstract_surface,
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 @@ _cairo_pdf_surface_stroke (void *abstract_surface,
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 @@ _cairo_pdf_surface_fill (void *abstract_surface,
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 @@ _cairo_pdf_surface_fill (void *abstract_surface,
op,
source,
&extents.bounded,
- FALSE);
+ 1.0, /* alpha */
+ FALSE); /* mask */
if (unlikely (status))
goto cleanup;
@@ -7598,6 +8187,10 @@ _cairo_pdf_surface_fill_stroke (void *abstract_surface,
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 @@ _cairo_pdf_surface_show_text_glyphs (void *abstract_surface,
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 @@ _cairo_pdf_surface_show_text_glyphs (void *abstract_surface,
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 @@ _cairo_pdf_surface_get_supported_mime_types (void *abstract_surface)
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 @@ static const cairo_surface_backend_t cairo_pdf_surface_backend = {
_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 @@ cairo_pdf_surface_paginated_backend = {
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,
};
diff --git a/Build/source/libs/cairo/cairo-src/src/cairo-pdf.h b/Build/source/libs/cairo/cairo-src/src/cairo-pdf.h
index 1bc8524f2b1..5be0b3f1bea 100644
--- a/Build/source/libs/cairo/cairo-src/src/cairo-pdf.h
+++ b/Build/source/libs/cairo/cairo-src/src/cairo-pdf.h
@@ -85,6 +85,73 @@ cairo_pdf_surface_set_size (cairo_surface_t *surface,
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 */
diff --git a/Build/source/libs/cairo/cairo-src/src/cairo-pen.c b/Build/source/libs/cairo/cairo-src/src/cairo-pen.c
index 61be0e8299d..9bf960423d0 100644
--- a/Build/source/libs/cairo/cairo-src/src/cairo-pen.c
+++ b/Build/source/libs/cairo/cairo-src/src/cairo-pen.c
@@ -106,7 +106,7 @@ _cairo_pen_fini (cairo_pen_t *pen)
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
diff --git a/Build/source/libs/cairo/cairo-src/src/cairo-png.c b/Build/source/libs/cairo/cairo-src/src/cairo-png.c
index e64b14a5fc0..ab0b9d0c51e 100644
--- a/Build/source/libs/cairo/cairo-src/src/cairo-png.c
+++ b/Build/source/libs/cairo/cairo-src/src/cairo-png.c
@@ -136,7 +136,7 @@ png_simple_error_callback (png_structp png,
/* 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 @@ png_simple_warning_callback (png_structp png,
*/
}
-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 @@ write_png (cairo_surface_t *surface,
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 @@ stdio_write_func (png_structp png, png_bytep data, png_size_t size)
/**
* 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 @@ stdio_write_func (png_structp png, png_bytep data, png_size_t size)
* 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 @@ cairo_surface_write_to_png (cairo_surface_t *surface,
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 @@ stream_write_func (png_structp png, png_bytep data, png_size_t size)
* 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 @@ stream_read_func (png_structp png, png_bytep data, png_size_t size)
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 @@ read_png (struct png_read_closure_t *png_closure)
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 @@ read_png (struct png_read_closure_t *png_closure)
}
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 @@ read_png (struct png_read_closure_t *png_closure)
/**
* 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 @@ read_png (struct png_read_closure_t *png_closure)
* %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 @@ cairo_image_surface_create_from_png (const char *filename)
{
struct png_read_closure_t png_closure;
cairo_surface_t *surface;
+ cairo_status_t status;
+
+ status = _cairo_fopen (filename, "rb", (FILE **) &png_closure.closure);
+
+ if (status != CAIRO_STATUS_SUCCESS)
+ return _cairo_surface_create_in_error (status);
- png_closure.closure = fopen (filename, "rb");
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_image_surface_create_from_png (const char *filename)
*
* %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
diff --git a/Build/source/libs/cairo/cairo-src/src/cairo-polygon-intersect.c b/Build/source/libs/cairo/cairo-src/src/cairo-polygon-intersect.c
index 8cb8fb1208b..001e55ee06a 100644
--- a/Build/source/libs/cairo/cairo-src/src/cairo-polygon-intersect.c
+++ b/Build/source/libs/cairo/cairo-src/src/cairo-polygon-intersect.c
@@ -447,7 +447,7 @@ edges_compare_x_for_y (const cairo_bo_edge_t *a,
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,13 +1107,14 @@ edges_start_or_continue (cairo_bo_edge_t *left,
int top,
cairo_polygon_t *polygon)
{
+ assert (right != NULL);
assert (right->deferred.other == NULL);
if (left->deferred.other == right)
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_start_or_continue (cairo_bo_edge_t *left,
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;
}
diff --git a/Build/source/libs/cairo/cairo-src/src/cairo-polygon-reduce.c b/Build/source/libs/cairo/cairo-src/src/cairo-polygon-reduce.c
index ea457fe4edf..da6c9ab7c78 100644
--- a/Build/source/libs/cairo/cairo-src/src/cairo-polygon-reduce.c
+++ b/Build/source/libs/cairo/cairo-src/src/cairo-polygon-reduce.c
@@ -445,7 +445,7 @@ edges_compare_x_for_y (const cairo_bo_edge_t *a,
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;
diff --git a/Build/source/libs/cairo/cairo-src/src/cairo-polygon.c b/Build/source/libs/cairo/cairo-src/src/cairo-polygon.c
index b0424f6e72e..0e0b8132853 100644
--- a/Build/source/libs/cairo/cairo-src/src/cairo-polygon.c
+++ b/Build/source/libs/cairo/cairo-src/src/cairo-polygon.c
@@ -248,7 +248,7 @@ _cairo_polygon_fini (cairo_polygon_t *polygon)
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 */
diff --git a/Build/source/libs/cairo/cairo-src/src/cairo-ps-surface-private.h b/Build/source/libs/cairo/cairo-src/src/cairo-ps-surface-private.h
index 1d5d27d4910..e1681c8894c 100644
--- a/Build/source/libs/cairo/cairo-src/src/cairo-ps-surface-private.h
+++ b/Build/source/libs/cairo/cairo-src/src/cairo-ps-surface-private.h
@@ -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,14 +76,15 @@ typedef struct cairo_ps_surface {
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 use_string_datasource;
+ cairo_bool_t paint_proc; /* TRUE if surface will be used in a PaintProc */
cairo_bool_t current_pattern_is_solid_color;
cairo_color_t current_color;
@@ -90,6 +104,8 @@ typedef struct cairo_ps_surface {
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 @@ typedef struct cairo_ps_surface {
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 */
diff --git a/Build/source/libs/cairo/cairo-src/src/cairo-ps-surface.c b/Build/source/libs/cairo/cairo-src/src/cairo-ps-surface.c
index 3b66b275d82..0a17b81afe3 100644
--- a/Build/source/libs/cairo/cairo-src/src/cairo-ps-surface.c
+++ b/Build/source/libs/cairo/cairo-src/src/cairo-ps-surface.c
@@ -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,7 +85,14 @@
#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) \
@@ -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,7 +161,30 @@ typedef enum {
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 @@ static cairo_bool_t
_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_level_strings[CAIRO_PS_LEVEL_LAST] =
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 @@ typedef struct _cairo_page_media {
} 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_ps_surface_emit_header (cairo_ps_surface_t *surface)
_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 @@ _cairo_ps_surface_emit_header (cairo_ps_surface_t *surface)
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 @@ _cairo_ps_surface_emit_header (cairo_ps_surface_t *surface)
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 @@ _cairo_ps_surface_emit_header (cairo_ps_surface_t *surface)
"/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 @@ _cairo_ps_surface_emit_header (cairo_ps_surface_t *surface)
"/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 @@ _cairo_ps_surface_emit_header (cairo_ps_surface_t *surface)
" } 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_ps_surface_emit_type3_font_subset (cairo_ps_surface_t *surface,
_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 @@ _cairo_ps_surface_emit_font_subsets (cairo_ps_surface_t *surface)
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 @@ _cairo_ps_surface_emit_footer (cairo_ps_surface_t *surface)
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 @@ _path_covers_bbox (cairo_ps_surface_t *surface,
_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 @@ _cairo_ps_surface_get_page_media (cairo_ps_surface_t *surface)
}
}
- 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_ps_surface_create_for_stream_internal (cairo_output_stream_t *stream,
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_ps_surface_create_for_stream_internal (cairo_output_stream_t *stream,
_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,17 +1184,23 @@ _cairo_ps_surface_create_for_stream_internal (cairo_output_stream_t *stream,
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->page_bbox.x = 0;
- surface->page_bbox.y = 0;
- surface->page_bbox.width = width;
- surface->page_bbox.height = height;
+ 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;
_cairo_surface_clipper_init (&surface->clipper,
_cairo_ps_surface_clipper_intersect_clip_path);
@@ -1081,6 +1216,14 @@ _cairo_ps_surface_create_for_stream_internal (cairo_output_stream_t *stream,
_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;
@@ -1095,6 +1238,7 @@ _cairo_ps_surface_create_for_stream_internal (cairo_output_stream_t *stream,
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 @@ cairo_ps_surface_set_size (cairo_surface_t *surface,
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_finish (void *abstract_surface)
_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_finish (void *abstract_surface)
_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 @@ CLEANUP:
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,133 +1876,97 @@ color_is_gray (double red, double green, double blue)
/**
* _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;
-
- 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;
- }
-
- 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;
+ *src_surface_extents = sub->extents;
+ *src_surface_bounded = TRUE;
+ *x_offset = -sub->extents.x;
+ *y_offset = -sub->extents.y;
}
- *source_surface = surf;
- return CAIRO_STATUS_SUCCESS;
- } else {
- status = _cairo_surface_acquire_source_image (surf, &image, image_extra);
+ cairo_surface_destroy (surf);
+ } else if (surf->type != CAIRO_SURFACE_TYPE_IMAGE) {
+ cairo_image_surface_t *image;
+ void *image_extra;
+
+ status = _cairo_surface_acquire_source_image (surf, &image, &image_extra);
if (unlikely (status))
return status;
- }
- } 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:
+ *src_surface_bounded = _cairo_surface_get_extents (&image->base, src_surface_extents);
+ _cairo_surface_release_source_image (surf, image, image_extra);
+ }
+ } else {
ASSERT_NOT_REACHED;
- break;
}
- *width = image->width;
- *height = image->height;
- *source_surface = &image->base;
return CAIRO_STATUS_SUCCESS;
}
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 @@ _cairo_ps_surface_release_source_surface_from_pattern (cairo_ps_surface_t
* @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_ps_surface_create_padded_image_from_image (cairo_ps_surface_t *
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_ps_surface_create_padded_image_from_image (cairo_ps_surface_t *
_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 @@ _cairo_ps_surface_create_padded_image_from_image (cairo_ps_surface_t *
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 @@ _cairo_ps_surface_analyze_surface_pattern_transparency (cairo_ps_surface_t
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;
+
+ status = _cairo_surface_acquire_source_image (source_surface, &image, &image_extra);
if (unlikely (status))
return status;
- image = (cairo_image_surface_t *) source;
if (image->base.status)
return image->base.status;
@@ -1969,7 +2091,8 @@ _cairo_ps_surface_analyze_surface_pattern_transparency (cairo_ps_surface_t
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 @@ _cairo_ps_surface_operation_supported (cairo_ps_surface_t *surface,
/* 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 @@ typedef struct _string_array_stream {
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++;
- }
-
- 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;
+ 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;
}
}
- /* 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++;
- }
+ c = *data++;
_cairo_output_stream_write (stream->output, &c, 1);
stream->column++;
- stream->string_size++;
+ /* 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;
+ }
+ }
+
+ /* 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,78 +2353,75 @@ _string_array_stream_write (cairo_output_stream_t *base,
}
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");
-
- status = _cairo_output_stream_get_status (stream->output);
+ if (!stream->use_strings || stream->string_size != 0)
+ _cairo_output_stream_printf (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;
}
_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;
}
_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_ps_surface_emit_base85_string (cairo_ps_surface_t *surface,
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 @@ _cairo_ps_surface_emit_base85_string (cairo_ps_surface_t *surface,
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 @@ _cairo_ps_surface_emit_base85_string (cairo_ps_surface_t *surface,
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,10 +2580,16 @@ _cairo_ps_surface_emit_image (cairo_ps_surface_t *surface,
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 (params->src_surface->status)
+ return params->src_surface->status;
- if (image_surf->base.status)
- return image_surf->base.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 &&
@@ -2464,16 +2600,16 @@ _cairo_ps_surface_emit_image (cairo_ps_surface_t *surface,
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;
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 @@ _cairo_ps_surface_emit_image (cairo_ps_surface_t *surface,
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 @@ _cairo_ps_surface_emit_image (cairo_ps_surface_t *surface,
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 @@ _cairo_ps_surface_emit_image (cairo_ps_surface_t *surface,
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 @@ _cairo_ps_surface_emit_image (cairo_ps_surface_t *surface,
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 @@ _cairo_ps_surface_emit_image (cairo_ps_surface_t *surface,
i++;
}
}
- if (stencil_mask)
+ if (params->stencil_mask)
continue;
/* image row*/
@@ -2664,11 +2787,11 @@ _cairo_ps_surface_emit_image (cairo_ps_surface_t *surface,
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_ps_surface_emit_image (cairo_ps_surface_t *surface,
_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 @@ _cairo_ps_surface_emit_image (cairo_ps_surface_t *surface,
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 @@ _cairo_ps_surface_emit_image (cairo_ps_surface_t *surface,
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 @@ bail0:
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 @@ _cairo_ps_surface_emit_jpeg_image (cairo_ps_surface_t *surface,
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 @@ _cairo_ps_surface_emit_jpeg_image (cairo_ps_surface_t *surface,
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_ps_surface_emit_jpeg_image (cairo_ps_surface_t *surface,
_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_ps_surface_emit_jpeg_image (cairo_ps_surface_t *surface,
_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 @@ _cairo_ps_surface_emit_jpeg_image (cairo_ps_surface_t *surface,
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;
+
+ if (unlikely (params->src_surface->status))
+ return params->src_surface->status;
+
+ 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;
- 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);
+ 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 (_cairo_surface_is_snapshot (recording_surface))
- free_me = recording_surface = _cairo_surface_snapshot_get_target (recording_surface);
+ /* 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;
- status =
- _cairo_recording_surface_get_bbox ((cairo_recording_surface_t *) recording_surface,
- &bbox,
- NULL);
- if (unlikely (status))
- goto err;
+ free (ccitt_params_string);
-#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
+ if (ccitt_params.columns <= 0 || ccitt_params.rows <= 0)
+ return CAIRO_INT_STATUS_UNSUPPORTED;
- 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);
+ /* 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;
+ }
- 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 (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,
+ "/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;
- 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);
+ "] 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));
+
+ 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_output_stream_printf (surface->stream, " Q\n");
+ _cairo_output_stream_printf (surface->stream,
+ " << /Columns %d /Rows %d /K %d\n",
+ ccitt_params.columns,
+ ccitt_params.rows,
+ ccitt_params.k);
- _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;
+ if (ccitt_params.end_of_line)
+ _cairo_output_stream_printf (surface->stream, " /EndOfLine true\n");
- _cairo_pdf_operators_set_cairo_to_pdf_matrix (&surface->pdf_operators,
- &surface->cairo_to_ps);
+ 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);
+ }
-err:
- cairo_surface_destroy (free_me);
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_surface_t *free_me = NULL;
cairo_int_status_t status;
+ cairo_surface_t *free_me = NULL;
+ 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 @@ _cairo_ps_surface_emit_recording_subsurface (cairo_ps_surface_t *surface,
#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,16 +3414,18 @@ _cairo_ps_surface_emit_recording_subsurface (cairo_ps_surface_t *surface,
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;
_cairo_pdf_operators_set_cairo_to_pdf_matrix (&surface->pdf_operators,
&surface->cairo_to_ps);
-
-err:
cairo_surface_destroy (free_me);
+
+ _cairo_array_truncate (&surface->recording_surf_stack, recording_surf_stack_size);
+
return status;
}
@@ -3145,44 +3471,351 @@ _cairo_ps_surface_emit_solid_pattern (cairo_ps_surface_t *surface,
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;
+
+ /* 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;
- 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;
+ if (mode == CAIRO_EMIT_SURFACE_EMIT && status == CAIRO_INT_STATUS_SUCCESS)
+ return status;
+ }
+
+ 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_jpeg_image (surface, surf, width, height);
- if (status != CAIRO_INT_STATUS_UNSUPPORTED)
+ 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 (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);
+ 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);
+ }
+
+ 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;
- status = _cairo_ps_surface_emit_image (surface, image,
- op, source_pattern->filter, stencil_mask);
+ 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,
@@ -3215,19 +3848,21 @@ _path_fixed_init_rectangle (cairo_path_fixed_t *path,
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 @@ _cairo_ps_surface_paint_surface (cairo_ps_surface_t *surface,
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_ps_surface_paint_surface (cairo_ps_surface_t *surface,
((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 @@ _cairo_ps_surface_paint_surface (cairo_ps_surface_t *surface,
"%% 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_ps_surface_paint_surface (cairo_ps_surface_t *surface,
}
_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,8 +3951,26 @@ _cairo_ps_surface_paint_surface (cairo_ps_surface_t *surface,
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, "[ ");
@@ -3319,18 +3978,13 @@ _cairo_ps_surface_paint_surface (cairo_ps_surface_t *surface,
_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_ps_surface_emit_surface_pattern (cairo_ps_surface_t *surface,
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,32 +4016,38 @@ _cairo_ps_surface_emit_surface_pattern (cairo_ps_surface_t *surface,
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;
}
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 @@ _cairo_ps_surface_emit_surface_pattern (cairo_ps_surface_t *surface,
* 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 @@ _cairo_ps_surface_emit_surface_pattern (cairo_ps_surface_t *surface,
* 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_ps_surface_emit_surface_pattern (cairo_ps_surface_t *surface,
}
_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);
+
+ 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);
+ }
- old_use_string_datasource = surface->use_string_datasource;
- surface->use_string_datasource = TRUE;
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 @@ _cairo_ps_surface_emit_surface_pattern (cairo_ps_surface_t *surface,
" /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 @@ _cairo_ps_surface_emit_surface_pattern (cairo_ps_surface_t *surface,
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 @@ _cairo_ps_surface_emit_surface_pattern (cairo_ps_surface_t *surface,
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 @@ _cairo_ps_surface_emit_surface_pattern (cairo_ps_surface_t *surface,
" ]\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 @@ _cairo_ps_surface_paint_pattern (cairo_ps_surface_t *surface,
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 @@ _cairo_ps_surface_paint_pattern (cairo_ps_surface_t *surface,
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_get_extents (void *abstract_surface,
{
cairo_ps_surface_t *surface = abstract_surface;
- rectangle->x = 0;
- rectangle->y = 0;
-
- /* 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);
+ if (surface->surface_bounded)
+ *rectangle = surface->surface_extents;
- return TRUE;
+ return surface->surface_bounded;
}
static void
@@ -4240,8 +4948,11 @@ _cairo_ps_surface_paint (void *abstract_surface,
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 @@ _cairo_ps_surface_get_supported_mime_types (void *abstract_surface)
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,34 +5256,57 @@ _cairo_ps_surface_set_paginated_mode (void *abstract_surface,
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",
@@ -4613,7 +5347,10 @@ _cairo_ps_surface_set_bounding_box (void *abstract_surface,
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_ps_surface_set_bounding_box (void *abstract_surface,
_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);
diff --git a/Build/source/libs/cairo/cairo-src/src/cairo-qt-surface.cpp b/Build/source/libs/cairo/cairo-src/src/cairo-qt-surface.cpp
index 7ddad77df37..5f669d8be38 100644
--- a/Build/source/libs/cairo/cairo-src/src/cairo-qt-surface.cpp
+++ b/Build/source/libs/cairo/cairo-src/src/cairo-qt-surface.cpp
@@ -631,7 +631,7 @@ map_qimage_to_image (QImage *qimg, const cairo_rectangle_int_t *extents)
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_qt_fast_fill (cairo_qt_surface_t *qs,
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_create (QPainter *painter)
{
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_create_with_qimage (cairo_format_t format,
{
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 @@ cairo_qt_surface_create_with_qpixmap (cairo_content_t content,
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));
diff --git a/Build/source/libs/cairo/cairo-src/src/cairo-quartz-font.c b/Build/source/libs/cairo/cairo-src/src/cairo-quartz-font.c
index feee61a0d86..8cb71434f89 100644
--- a/Build/source/libs/cairo/cairo-src/src/cairo-quartz-font.c
+++ b/Build/source/libs/cairo/cairo-src/src/cairo-quartz-font.c
@@ -81,6 +81,14 @@ static void (*CGFontGetGlyphsForUnicharsPtr) (CGFontRef, const UniChar[], const
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 ATSFontRef (*FMGetATSFontRefFromFontPtr) (FMFont iFont) = NULL;
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 @@ quartz_font_ensure_symbols(void)
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 @@ quartz_font_ensure_symbols(void)
CGFontGetGlyphsForUnicharsPtr &&
CGFontGetUnitsPerEmPtr &&
CGFontGetGlyphAdvancesPtr &&
+ ((CTFontCreateWithGraphicsFontPtr && CTFontCreatePathForGlyphPtr) || CGFontGetGlyphPathPtr) &&
(CGFontGetHMetricsPtr || (CGFontGetAscentPtr && CGFontGetDescentPtr && CGFontGetLeadingPtr)))
_cairo_quartz_font_symbols_present = TRUE;
@@ -178,7 +196,7 @@ _cairo_quartz_font_face_create_for_toy (cairo_toy_font_face_t *toy_face,
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 @@ _cairo_quartz_font_face_scaled_font_create (void *abstract_face,
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 @@ cairo_quartz_font_face_create_for_cgfont (CGFontRef font)
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 @@ _cairo_quartz_scaled_font_fini(void *abstract_font)
{
}
-#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 @@ _cairo_quartz_init_glyph_metrics (cairo_quartz_scaled_font_t *font,
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 @@ _cairo_quartz_init_glyph_path (cairo_quartz_scaled_font_t *font,
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 @@ _cairo_quartz_init_glyph_path (cairo_quartz_scaled_font_t *font,
-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 @@ _cairo_quartz_init_glyph_surface (cairo_quartz_scaled_font_t *font,
* 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_ucs4_to_index (void *abstract_font,
{
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
diff --git a/Build/source/libs/cairo/cairo-src/src/cairo-quartz-image-surface.c b/Build/source/libs/cairo/cairo-src/src/cairo-quartz-image-surface.c
index 498a7b06436..84d56c9b471 100644
--- a/Build/source/libs/cairo/cairo-src/src/cairo-quartz-image-surface.c
+++ b/Build/source/libs/cairo/cairo-src/src/cairo-quartz-image-surface.c
@@ -332,7 +332,7 @@ cairo_quartz_image_surface_create (cairo_surface_t *surface)
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_quartz_image_surface_create (cairo_surface_t *surface)
_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;
diff --git a/Build/source/libs/cairo/cairo-src/src/cairo-quartz-image.h b/Build/source/libs/cairo/cairo-src/src/cairo-quartz-image.h
index dae234dacae..0dd5abb4fd2 100644
--- a/Build/source/libs/cairo/cairo-src/src/cairo-quartz-image.h
+++ b/Build/source/libs/cairo/cairo-src/src/cairo-quartz-image.h
@@ -1,6 +1,6 @@
/* cairo - a vector graphics library with display and print output
*
- * Copyright © 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
diff --git a/Build/source/libs/cairo/cairo-src/src/cairo-quartz-private.h b/Build/source/libs/cairo/cairo-src/src/cairo-quartz-private.h
index 3ef14c3ae60..42e1f9e9161 100644
--- a/Build/source/libs/cairo/cairo-src/src/cairo-quartz-private.h
+++ b/Build/source/libs/cairo/cairo-src/src/cairo-quartz-private.h
@@ -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 @@ typedef enum {
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;
diff --git a/Build/source/libs/cairo/cairo-src/src/cairo-quartz-surface.c b/Build/source/libs/cairo/cairo-src/src/cairo-quartz-surface.c
index 1116ff94c1e..65d03080a73 100644
--- a/Build/source/libs/cairo/cairo-src/src/cairo-quartz-surface.c
+++ b/Build/source/libs/cairo/cairo-src/src/cairo-quartz-surface.c
@@ -508,9 +508,13 @@ _cairo_cgcontext_set_cairo_operator (CGContextRef context, cairo_operator_t op)
/* 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,14 +609,25 @@ _cairo_quartz_cairo_line_join_to_quartz (cairo_line_join_t cjoin)
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:
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 @@ _cairo_surface_to_cgimage (cairo_surface_t *source,
}
}
- 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 @@ _cairo_quartz_cairo_repeating_surface_pattern_to_quartz (cairo_quartz_surface_t
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 @@ _cairo_quartz_surface_create_internal (CGContextRef cgContext,
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_quartz_surface_create_internal (CGContextRef cgContext,
_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);
diff --git a/Build/source/libs/cairo/cairo-src/src/cairo-quartz.h b/Build/source/libs/cairo/cairo-src/src/cairo-quartz.h
index 9be5f9ae5cf..9e11e876fee 100644
--- a/Build/source/libs/cairo/cairo-src/src/cairo-quartz.h
+++ b/Build/source/libs/cairo/cairo-src/src/cairo-quartz.h
@@ -1,6 +1,6 @@
/* cairo - a vector graphics library with display and print output
*
- * Copyright © 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
diff --git a/Build/source/libs/cairo/cairo-src/src/cairo-recording-surface-private.h b/Build/source/libs/cairo/cairo-src/src/cairo-recording-surface-private.h
index 456c63389b7..c1827f5b3d6 100644
--- a/Build/source/libs/cairo/cairo-src/src/cairo-recording-surface-private.h
+++ b/Build/source/libs/cairo/cairo-src/src/cairo-recording-surface-private.h
@@ -49,6 +49,9 @@ typedef enum {
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 @@ typedef struct _cairo_command_show_text_glyphs {
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 @@ typedef union _cairo_command {
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_recording_surface_replay_with_clip (cairo_surface_t *surface,
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,
diff --git a/Build/source/libs/cairo/cairo-src/src/cairo-recording-surface.c b/Build/source/libs/cairo/cairo-src/src/cairo-recording-surface.c
index 78e7cfa7efc..6df8b0821e0 100644
--- a/Build/source/libs/cairo/cairo-src/src/cairo-recording-surface.c
+++ b/Build/source/libs/cairo/cairo-src/src/cairo-recording-surface.c
@@ -158,7 +158,7 @@ static int bbtree_left_or_right (struct bbtree *bbt,
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,14 +386,15 @@ cairo_recording_surface_create (cairo_content_t content,
{
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));
_cairo_surface_init (&surface->base,
&cairo_recording_surface_backend,
NULL, /* device */
- content);
+ content,
+ TRUE); /* is_vector */
surface->unbounded = TRUE;
@@ -482,7 +483,16 @@ _cairo_recording_surface_finish (void *abstract_surface)
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 @@ attach_proxy (cairo_surface_t *source,
{
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_recording_surface_reset (cairo_recording_surface_t *surface)
_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 @@ _cairo_recording_surface_paint (void *abstract_surface,
(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 @@ _cairo_recording_surface_paint (void *abstract_surface,
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 @@ _cairo_recording_surface_mask (void *abstract_surface,
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 @@ _cairo_recording_surface_stroke (void *abstract_surface,
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 @@ _cairo_recording_surface_fill (void *abstract_surface,
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 @@ _cairo_recording_surface_show_text_glyphs (void *abstract_surface,
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 @@ _cairo_recording_surface_show_text_glyphs (void *abstract_surface,
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 @@ CLEANUP_COMPOSITE:
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_recording_surface_copy__paint (cairo_recording_surface_t *surface,
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_recording_surface_copy__mask (cairo_recording_surface_t *surface,
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_recording_surface_copy__stroke (cairo_recording_surface_t *surface,
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_recording_surface_copy__fill (cairo_recording_surface_t *surface,
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_recording_surface_copy__glyphs (cairo_recording_surface_t *surface,
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 @@ _cairo_recording_surface_copy__glyphs (cairo_recording_surface_t *surface,
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 @@ err:
}
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 @@ _cairo_recording_surface_copy (cairo_recording_surface_t *dst,
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,14 +1560,15 @@ _cairo_recording_surface_snapshot (void *abstract_other)
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));
_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 @@ static const cairo_surface_backend_t cairo_recording_surface_backend = {
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 @@ _cairo_recording_surface_get_path (cairo_surface_t *abstract_surface,
break;
}
+ case CAIRO_COMMAND_TAG:
+ break;
+
default:
ASSERT_NOT_REACHED;
}
@@ -1674,14 +1816,14 @@ _cairo_recording_surface_replay_internal (cairo_recording_surface_t *surface,
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)
{
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 @@ _cairo_recording_surface_replay_internal (cairo_recording_surface_t *surface,
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_recording_surface_replay_internal (cairo_recording_surface_t *surface,
_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 @@ _cairo_recording_surface_replay_internal (cairo_recording_surface_t *surface,
}
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 @@ _cairo_recording_surface_replay_one (cairo_recording_surface_t *surface,
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_recording_surface_replay (cairo_surface_t *surface,
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 @@ _cairo_recording_surface_replay_with_clip (cairo_surface_t *surface,
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_recording_surface_replay_with_clip (cairo_surface_t *surface,
*/
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 @@ _cairo_recording_surface_replay_region (cairo_surface_t *surface,
{
return _cairo_recording_surface_replay_internal ((cairo_recording_surface_t *) surface,
surface_extents, NULL,
- target, NULL,
+ target, NULL, FALSE,
CAIRO_RECORDING_REPLAY,
region);
}
diff --git a/Build/source/libs/cairo/cairo-src/src/cairo-region.c b/Build/source/libs/cairo/cairo-src/src/cairo-region.c
index ccfb2200e14..c1d35e174ae 100644
--- a/Build/source/libs/cairo/cairo-src/src/cairo-region.c
+++ b/Build/source/libs/cairo/cairo-src/src/cairo-region.c
@@ -107,6 +107,10 @@ _cairo_region_create_in_error (cairo_status_t status)
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 @@ _cairo_region_fini (cairo_region_t *region)
{
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)));
}
/**
diff --git a/Build/source/libs/cairo/cairo-src/src/cairo-scaled-font-private.h b/Build/source/libs/cairo/cairo-src/src/cairo-scaled-font-private.h
index da7b3469834..317d2119795 100644
--- a/Build/source/libs/cairo/cairo-src/src/cairo-scaled-font-private.h
+++ b/Build/source/libs/cairo/cairo-src/src/cairo-scaled-font-private.h
@@ -141,6 +141,7 @@ struct _cairo_scaled_glyph {
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 @@ _cairo_scaled_glyph_attach_private (cairo_scaled_glyph_t *scaled_glyph,
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
diff --git a/Build/source/libs/cairo/cairo-src/src/cairo-scaled-font-subsets.c b/Build/source/libs/cairo/cairo-src/src/cairo-scaled-font-subsets.c
index a239ec9b33e..5c1afd2d03e 100644
--- a/Build/source/libs/cairo/cairo-src/src/cairo-scaled-font-subsets.c
+++ b/Build/source/libs/cairo/cairo-src/src/cairo-scaled-font-subsets.c
@@ -167,7 +167,7 @@ _cairo_sub_font_glyph_create (unsigned long scaled_font_glyph_index,
{
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_create (cairo_scaled_font_subsets_t *parent,
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 @@ _cairo_sub_font_glyph_lookup_unicode (cairo_scaled_font_t *scaled_font,
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 @@ _cairo_sub_font_glyph_map_to_unicode (cairo_sub_font_glyph_t *sub_font_glyph,
}
} 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 @@ _cairo_sub_font_map_glyph (cairo_sub_font_t *sub_font,
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_create_internal (cairo_subsets_type_t type)
{
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 @@ _cairo_string_init_key (cairo_string_entry_t *key, char *s)
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);
diff --git a/Build/source/libs/cairo/cairo-src/src/cairo-scaled-font.c b/Build/source/libs/cairo/cairo-src/src/cairo-scaled-font.c
index 53a370d3acc..8dff57d9533 100644
--- a/Build/source/libs/cairo/cairo-src/src/cairo-scaled-font.c
+++ b/Build/source/libs/cairo/cairo-src/src/cairo-scaled-font.c
@@ -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 @@ static cairo_cache_t cairo_scaled_glyph_page_cache;
#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_scaled_glyph_fini (cairo_scaled_font_t *scaled_font,
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_scaled_font_map_lock (void)
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 @@ _cairo_scaled_glyph_page_pluck (void *closure)
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 @@ _cairo_scaled_font_register_placeholder_and_unlock_font_map (cairo_scaled_font_t
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_scaled_font_create_in_error (cairo_status_t status)
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 @@ _cairo_scaled_font_reset_static_data (void)
* @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 @@ cairo_scaled_font_text_to_glyphs (cairo_scaled_font_t *scaled_font,
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 @@ cairo_scaled_font_text_to_glyphs (cairo_scaled_font_t *scaled_font,
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,13 +2827,31 @@ _cairo_scaled_glyph_set_recording_surface (cairo_scaled_glyph_t *scaled_glyph,
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)
{
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 @@ _cairo_scaled_font_allocate_glyph (cairo_scaled_font_t *scaled_font,
}
}
- 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_scaled_font_get_font_options (cairo_scaled_font_t *scaled_font,
_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;
+}
diff --git a/Build/source/libs/cairo/cairo-src/src/cairo-script-surface.c b/Build/source/libs/cairo/cairo-src/src/cairo-script-surface.c
index a4cefdebb4b..7db7dc5b0df 100644
--- a/Build/source/libs/cairo/cairo-src/src/cairo-script-surface.c
+++ b/Build/source/libs/cairo/cairo-src/src/cairo-script-surface.c
@@ -262,8 +262,9 @@ _bitmap_next_id (struct _bitmap *b,
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,14 +1105,15 @@ attach_snapshot (cairo_script_context_t *ctx,
if (! ctx->attach_snapshots)
return;
- surface = malloc (sizeof (*surface));
+ surface = _cairo_malloc (sizeof (*surface));
if (unlikely (surface == NULL))
return;
_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 @@ static cairo_status_t
_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 @@ _write_image_surface (cairo_output_stream_t *output,
}
#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_script_surface_finish (void *abstract_surface)
}
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 @@ _emit_type42_font (cairo_script_surface_t *surface,
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 @@ _emit_scaled_font_init (cairo_script_surface_t *surface,
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,14 +3644,15 @@ _cairo_script_surface_create_internal (cairo_script_context_t *ctx,
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));
_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_create_internal (cairo_output_stream_t *stream)
{
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));
diff --git a/Build/source/libs/cairo/cairo-src/src/cairo-skia.h b/Build/source/libs/cairo/cairo-src/src/cairo-skia.h
deleted file mode 100644
index 99b92865699..00000000000
--- a/Build/source/libs/cairo/cairo-src/src/cairo-skia.h
+++ /dev/null
@@ -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@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
diff --git a/Build/source/libs/cairo/cairo-src/src/cairo-spans-private.h b/Build/source/libs/cairo/cairo-src/src/cairo-spans-private.h
index b158f4d360a..653183fb1c8 100644
--- a/Build/source/libs/cairo/cairo-src/src/cairo-spans-private.h
+++ b/Build/source/libs/cairo/cairo-src/src/cairo-spans-private.h
@@ -168,6 +168,10 @@ _cairo_botor_scan_converter_init (cairo_botor_scan_converter_t *self,
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 *
diff --git a/Build/source/libs/cairo/cairo-src/src/cairo-spans.c b/Build/source/libs/cairo/cairo-src/src/cairo-spans.c
index 182390c205a..59452c0ba69 100644
--- a/Build/source/libs/cairo/cairo-src/src/cairo-spans.c
+++ b/Build/source/libs/cairo/cairo-src/src/cairo-spans.c
@@ -128,6 +128,10 @@ _cairo_scan_converter_create_in_error (cairo_status_t status)
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 @@ _cairo_span_renderer_create_in_error (cairo_status_t status)
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;
}
diff --git a/Build/source/libs/cairo/cairo-src/src/cairo-stroke-style.c b/Build/source/libs/cairo/cairo-src/src/cairo-stroke-style.c
index 51c9414c042..9c373c33327 100644
--- a/Build/source/libs/cairo/cairo-src/src/cairo-stroke-style.c
+++ b/Build/source/libs/cairo/cairo-src/src/cairo-stroke-style.c
@@ -91,7 +91,7 @@ _cairo_stroke_style_fini (cairo_stroke_style_t *style)
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)));
}
/*
diff --git a/Build/source/libs/cairo/cairo-src/src/cairo-surface-backend-private.h b/Build/source/libs/cairo/cairo-src/src/cairo-surface-backend-private.h
index 955a79ff5c3..bcda9aed155 100644
--- a/Build/source/libs/cairo/cairo-src/src/cairo-surface-backend-private.h
+++ b/Build/source/libs/cairo/cairo-src/src/cairo-surface-backend-private.h
@@ -200,6 +200,18 @@ struct _cairo_surface_backend {
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
diff --git a/Build/source/libs/cairo/cairo-src/src/cairo-surface-observer.c b/Build/source/libs/cairo/cairo-src/src/cairo-surface-observer.c
index e6f78e6da6f..9c4432e246f 100644
--- a/Build/source/libs/cairo/cairo-src/src/cairo-surface-observer.c
+++ b/Build/source/libs/cairo/cairo-src/src/cairo-surface-observer.c
@@ -348,7 +348,7 @@ _cairo_device_create_observer_internal (cairo_device_t *target,
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_create_observer_internal (cairo_device_t *device,
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 @@ _cairo_surface_observer_add_callback (cairo_list_t *head,
{
struct callback_list *cb;
- cb = malloc (sizeof (*cb));
+ cb = _cairo_malloc (sizeof (*cb));
if (unlikely (cb == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
diff --git a/Build/source/libs/cairo/cairo-src/src/cairo-surface-private.h b/Build/source/libs/cairo/cairo-src/src/cairo-surface-private.h
index f20ab073932..e4ad5f3b18d 100644
--- a/Build/source/libs/cairo/cairo-src/src/cairo-surface-private.h
+++ b/Build/source/libs/cairo/cairo-src/src/cairo-surface-private.h
@@ -70,6 +70,7 @@ struct _cairo_surface {
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;
diff --git a/Build/source/libs/cairo/cairo-src/src/cairo-surface-snapshot.c b/Build/source/libs/cairo/cairo-src/src/cairo-surface-snapshot.c
index 68bf9054ecd..a8b8c0e45d8 100644
--- a/Build/source/libs/cairo/cairo-src/src/cairo-surface-snapshot.c
+++ b/Build/source/libs/cairo/cairo-src/src/cairo-surface-snapshot.c
@@ -99,15 +99,18 @@ _cairo_surface_snapshot_acquire_source_image (void *abstract_
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);
if (unlikely (status)) {
cairo_surface_destroy (extra->target);
free (extra);
+ extra = NULL;
}
*extra_out = extra;
@@ -258,14 +261,15 @@ _cairo_surface_snapshot (cairo_surface_t *surface)
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));
_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);
diff --git a/Build/source/libs/cairo/cairo-src/src/cairo-surface-subsurface.c b/Build/source/libs/cairo/cairo-src/src/cairo-surface-subsurface.c
index b7dfd9d9e0c..b2a10e9bce3 100644
--- a/Build/source/libs/cairo/cairo-src/src/cairo-surface-subsurface.c
+++ b/Build/source/libs/cairo/cairo-src/src/cairo-surface-subsurface.c
@@ -462,7 +462,7 @@ cairo_surface_create_for_rectangle (cairo_surface_t *target,
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_create_for_rectangle (cairo_surface_t *target,
_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,14 +522,15 @@ _cairo_surface_create_for_rectangle_int (cairo_surface_t *target,
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));
_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;
diff --git a/Build/source/libs/cairo/cairo-src/src/cairo-surface-wrapper-private.h b/Build/source/libs/cairo/cairo-src/src/cairo-surface-wrapper-private.h
index 6529ebc1115..fd22bd7e6c2 100644
--- a/Build/source/libs/cairo/cairo-src/src/cairo-surface-wrapper-private.h
+++ b/Build/source/libs/cairo/cairo-src/src/cairo-surface-wrapper-private.h
@@ -159,6 +159,17 @@ _cairo_surface_wrapper_show_text_glyphs (cairo_surface_wrapper_t *wrapper,
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_surface_wrapper_is_active (cairo_surface_wrapper_t *wrapper)
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
diff --git a/Build/source/libs/cairo/cairo-src/src/cairo-surface-wrapper.c b/Build/source/libs/cairo/cairo-src/src/cairo-surface-wrapper.c
index 9236c8bf42e..47155c3f799 100644
--- a/Build/source/libs/cairo/cairo-src/src/cairo-surface-wrapper.c
+++ b/Build/source/libs/cairo/cairo-src/src/cairo-surface-wrapper.c
@@ -81,9 +81,6 @@ _cairo_surface_wrapper_get_transform (cairo_surface_wrapper_t *wrapper,
{
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 @@ _cairo_surface_wrapper_get_inverse_transform (cairo_surface_wrapper_t *wrapper,
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 @@ _cairo_surface_wrapper_get_clip (cairo_surface_wrapper_t *wrapper,
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 @@ _cairo_surface_wrapper_show_text_glyphs (cairo_surface_wrapper_t *wrapper,
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_surface_wrapper_fini (cairo_surface_wrapper_t *wrapper)
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;
+
+ if (!surface_is_unbounded)
+ has_clip = _cairo_surface_get_extents (wrapper->target, &clip);
- has_clip = _cairo_surface_get_extents (wrapper->target, &clip);
if (wrapper->clip) {
if (has_clip) {
if (! _cairo_rectangle_intersect (&clip,
diff --git a/Build/source/libs/cairo/cairo-src/src/cairo-surface.c b/Build/source/libs/cairo/cairo-src/src/cairo-surface.c
index fa0ca37db9c..596ca250d4e 100644
--- a/Build/source/libs/cairo/cairo-src/src/cairo-surface.c
+++ b/Build/source/libs/cairo/cairo-src/src/cairo-surface.c
@@ -113,7 +113,8 @@ const cairo_surface_t name = { \
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 @@ void
_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 @@ _cairo_surface_init (cairo_surface_t *surface,
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 @@ cairo_surface_create_similar (cairo_surface_t *other,
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 @@ _cairo_surface_create_scratch (cairo_surface_t *other,
* @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_surface_finish (cairo_surface_t *surface)
{
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_finish (cairo_surface_t *surface)
_cairo_surface_set_error (surface, status);
}
+ surface->finished = TRUE;
+
assert (surface->snapshot_of == NULL);
assert (!_cairo_surface_has_snapshots (surface));
}
@@ -1225,6 +1224,80 @@ _cairo_mime_data_destroy (void *ptr)
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:
*
@@ -1315,7 +1388,8 @@ _cairo_mime_data_destroy (void *ptr)
* 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 @@ cairo_surface_set_mime_data (cairo_surface_t *surface,
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 @@ cairo_surface_set_mime_data (cairo_surface_t *surface,
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_surface_copy_mime_data (cairo_surface_t *dst,
_cairo_mime_data_reference,
NULL);
+ dst->is_clear = FALSE;
+
return CAIRO_STATUS_SUCCESS;
}
@@ -2518,6 +2596,200 @@ cairo_surface_has_show_text_glyphs (cairo_surface_t *surface)
}
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 @@ _cairo_surface_show_text_glyphs (cairo_surface_t *surface,
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 @@ _cairo_surface_show_text_glyphs (cairo_surface_t *surface,
}
}
+DONE:
if (status != CAIRO_INT_STATUS_NOTHING_TO_DO) {
surface->is_clear = FALSE;
surface->serial++;
@@ -2632,6 +2921,42 @@ _cairo_surface_show_text_glyphs (cairo_surface_t *surface,
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 @@ _cairo_surface_create_in_error (cairo_status_t status)
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;
diff --git a/Build/source/libs/cairo/cairo-src/src/cairo-svg-surface-private.h b/Build/source/libs/cairo/cairo-src/src/cairo-svg-surface-private.h
index ddbf464b1d2..6f693252a89 100644
--- a/Build/source/libs/cairo/cairo-src/src/cairo-svg-surface-private.h
+++ b/Build/source/libs/cairo/cairo-src/src/cairo-svg-surface-private.h
@@ -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 @@ typedef struct cairo_svg_surface {
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;
diff --git a/Build/source/libs/cairo/cairo-src/src/cairo-svg-surface.c b/Build/source/libs/cairo/cairo-src/src/cairo-svg-surface.c
index d9f4b92652e..dd37198eff3 100644
--- a/Build/source/libs/cairo/cairo-src/src/cairo-svg-surface.c
+++ b/Build/source/libs/cairo/cairo-src/src/cairo-svg-surface.c
@@ -94,6 +94,7 @@ static const char *_cairo_svg_supported_mime_types[] =
{
CAIRO_MIME_TYPE_JPEG,
CAIRO_MIME_TYPE_PNG,
+ CAIRO_MIME_TYPE_UNIQUE_ID,
CAIRO_MIME_TYPE_URI,
NULL
};
@@ -121,6 +122,20 @@ static const char * _cairo_svg_internal_version_strings[CAIRO_SVG_VERSION_LAST]
"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 @@ struct cairo_svg_document {
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 @@ static cairo_surface_t *
_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 @@ cairo_svg_surface_create_for_stream (cairo_write_func_t write_func,
* 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,6 +420,164 @@ cairo_svg_version_to_string (cairo_svg_version_t version)
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,23 +649,26 @@ static cairo_surface_t *
_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));
_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 @@ _cairo_svg_surface_create_for_document (cairo_svg_document_t *document,
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 @@ _cairo_svg_surface_create_for_stream_internal (cairo_output_stream_t *stream,
}
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_svg_surface_finish (void *abstract_surface)
_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 @@ _cairo_svg_surface_emit_attr_value (cairo_output_stream_t *stream,
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 @@ _cairo_svg_surface_emit_surface (cairo_svg_document_t *document,
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_svg_surface_emit_surface (cairo_svg_document_t *document,
_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,17 +1521,29 @@ _cairo_svg_surface_emit_composite_surface_pattern (cairo_output_stream_t *outp
{
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);
/* 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_svg_surface_emit_composite_surface_pattern (cairo_output_stream_t *outp
_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 @@ _cairo_svg_surface_emit_composite_surface_pattern (cairo_output_stream_t *outp
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 @@ _cairo_svg_surface_emit_recording_surface (cairo_svg_document_t *document,
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 @@ _cairo_svg_surface_emit_recording_surface (cairo_svg_document_t *document,
"<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 @@ _cairo_svg_surface_emit_recording_surface (cairo_svg_document_t *document,
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,17 +1708,28 @@ _cairo_svg_surface_emit_composite_recording_pattern (cairo_output_stream_t *outp
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);
/* 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_svg_surface_emit_composite_recording_pattern (cairo_output_stream_t *outp
_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 @@ _cairo_svg_surface_get_extents (void *abstract_surface,
rectangle->width = ceil (surface->width);
rectangle->height = ceil (surface->height);
- return TRUE;
+ return surface->surface_bounded;
}
static cairo_status_t
@@ -2658,7 +2862,7 @@ _cairo_svg_document_create (cairo_output_stream_t *output_stream,
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 @@ _cairo_svg_document_create (cairo_output_stream_t *output_stream,
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,9 +2982,10 @@ _cairo_svg_document_finish (cairo_svg_document_t *document)
"<?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, document->height,
+ document->width, _cairo_svg_unit_strings [document->unit],
+ document->height, _cairo_svg_unit_strings [document->unit],
document->width, document->height,
_cairo_svg_internal_version_strings [document->svg_version]);
@@ -2851,13 +3057,15 @@ _cairo_svg_document_finish (cairo_svg_document_t *document)
return status;
}
-static void
+static cairo_int_status_t
_cairo_svg_surface_set_paginated_mode (void *abstract_surface,
cairo_paginated_mode_t paginated_mode)
{
cairo_svg_surface_t *surface = abstract_surface;
surface->paginated_mode = paginated_mode;
+
+ return CAIRO_STATUS_SUCCESS;
}
static cairo_bool_t
diff --git a/Build/source/libs/cairo/cairo-src/src/cairo-svg.h b/Build/source/libs/cairo/cairo-src/src/cairo-svg.h
index 592c645f627..4d24857bcaa 100644
--- a/Build/source/libs/cairo/cairo-src/src/cairo-svg.h
+++ b/Build/source/libs/cairo/cairo-src/src/cairo-svg.h
@@ -53,6 +53,46 @@ typedef enum _cairo_svg_version {
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_svg_get_versions (cairo_svg_version_t const **versions,
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 */
diff --git a/Build/source/libs/cairo/cairo-src/src/cairo-tag-attributes-private.h b/Build/source/libs/cairo/cairo-src/src/cairo-tag-attributes-private.h
new file mode 100644
index 00000000000..3f5fa5b64a2
--- /dev/null
+++ b/Build/source/libs/cairo/cairo-src/src/cairo-tag-attributes-private.h
@@ -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@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 */
diff --git a/Build/source/libs/cairo/cairo-src/src/cairo-tag-attributes.c b/Build/source/libs/cairo/cairo-src/src/cairo-tag-attributes.c
new file mode 100644
index 00000000000..44b1147fb91
--- /dev/null
+++ b/Build/source/libs/cairo/cairo-src/src/cairo-tag-attributes.c
@@ -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@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;
+}
diff --git a/Build/source/libs/cairo/cairo-src/src/cairo-tag-stack-private.h b/Build/source/libs/cairo/cairo-src/src/cairo-tag-stack-private.h
new file mode 100644
index 00000000000..4af2a85dec5
--- /dev/null
+++ b/Build/source/libs/cairo/cairo-src/src/cairo-tag-stack-private.h
@@ -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@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 */
diff --git a/Build/source/libs/cairo/cairo-src/src/cairo-tag-stack.c b/Build/source/libs/cairo/cairo-src/src/cairo-tag-stack.c
new file mode 100644
index 00000000000..7c2d5245e0a
--- /dev/null
+++ b/Build/source/libs/cairo/cairo-src/src/cairo-tag-stack.c
@@ -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@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;
+}
diff --git a/Build/source/libs/cairo/cairo-src/src/cairo-tee-surface.c b/Build/source/libs/cairo/cairo-src/src/cairo-tee-surface.c
index 294e5f162e2..7a94c9bca4c 100644
--- a/Build/source/libs/cairo/cairo-src/src/cairo-tee-surface.c
+++ b/Build/source/libs/cairo/cairo-src/src/cairo-tee-surface.c
@@ -428,14 +428,15 @@ cairo_tee_surface_create (cairo_surface_t *master)
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));
_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);
diff --git a/Build/source/libs/cairo/cairo-src/src/cairo-tor-scan-converter.c b/Build/source/libs/cairo/cairo-src/src/cairo-tor-scan-converter.c
index b1b51872b19..e8142d5bcf6 100644
--- a/Build/source/libs/cairo/cairo-src/src/cairo-tor-scan-converter.c
+++ b/Build/source/libs/cairo/cairo-src/src/cairo-tor-scan-converter.c
@@ -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 @@ _pool_chunk_create(struct pool *pool, size_t size)
{
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_create (int xmin,
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;
diff --git a/Build/source/libs/cairo/cairo-src/src/cairo-tor22-scan-converter.c b/Build/source/libs/cairo/cairo-src/src/cairo-tor22-scan-converter.c
index 4cec5ee4f37..bf44742b0b3 100644
--- a/Build/source/libs/cairo/cairo-src/src/cairo-tor22-scan-converter.c
+++ b/Build/source/libs/cairo/cairo-src/src/cairo-tor22-scan-converter.c
@@ -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 @@ _pool_chunk_create(struct pool *pool, size_t size)
{
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_create (int xmin,
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;
diff --git a/Build/source/libs/cairo/cairo-src/src/cairo-toy-font-face.c b/Build/source/libs/cairo/cairo-src/src/cairo-toy-font-face.c
index 516f391953f..3d2217daef8 100644
--- a/Build/source/libs/cairo/cairo-src/src/cairo-toy-font-face.c
+++ b/Build/source/libs/cairo/cairo-src/src/cairo-toy-font-face.c
@@ -312,7 +312,7 @@ cairo_toy_font_face_create (const char *family,
}
/* 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;
diff --git a/Build/source/libs/cairo/cairo-src/src/cairo-traps.c b/Build/source/libs/cairo/cairo-src/src/cairo-traps.c
index 3aa0052f91f..1b748484338 100644
--- a/Build/source/libs/cairo/cairo-src/src/cairo-traps.c
+++ b/Build/source/libs/cairo/cairo-src/src/cairo-traps.c
@@ -113,7 +113,7 @@ _cairo_traps_fini (cairo_traps_t *traps)
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 */
diff --git a/Build/source/libs/cairo/cairo-src/src/cairo-tristrip.c b/Build/source/libs/cairo/cairo-src/src/cairo-tristrip.c
index bb4972f5003..bcf3b237167 100644
--- a/Build/source/libs/cairo/cairo-src/src/cairo-tristrip.c
+++ b/Build/source/libs/cairo/cairo-src/src/cairo-tristrip.c
@@ -58,7 +58,7 @@ _cairo_tristrip_fini (cairo_tristrip_t *strip)
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)));
}
diff --git a/Build/source/libs/cairo/cairo-src/src/cairo-truetype-subset.c b/Build/source/libs/cairo/cairo-src/src/cairo-truetype-subset.c
index b650ebe8678..6cef4ee423c 100644
--- a/Build/source/libs/cairo/cairo-src/src/cairo-truetype-subset.c
+++ b/Build/source/libs/cairo/cairo-src/src/cairo-truetype-subset.c
@@ -77,22 +77,22 @@ struct _cairo_truetype_font {
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_hhea_t, 36);
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_create (cairo_scaled_font_subset_t *scaled_font_subset,
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,9 +159,15 @@ _cairo_truetype_font_create (cairo_scaled_font_subset_t *scaled_font_subset,
* 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,
@@ -187,12 +193,12 @@ _cairo_truetype_font_create (cairo_scaled_font_subset_t *scaled_font_subset,
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,21 +211,21 @@ _cairo_truetype_font_create (cairo_scaled_font_subset_t *scaled_font_subset,
/* 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;
}
/* 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;
}
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 @@ _cairo_truetype_font_create (cairo_scaled_font_subset_t *scaled_font_subset,
/* 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 @@ _cairo_truetype_font_create (cairo_scaled_font_subset_t *scaled_font_subset,
}
/* 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 @@ _cairo_truetype_font_create (cairo_scaled_font_subset_t *scaled_font_subset,
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 @@ static void
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 @@ cairo_truetype_font_write_glyf_table (cairo_truetype_font_t *font,
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 @@ cairo_truetype_font_write_glyf_table (cairo_truetype_font_t *font,
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 @@ cairo_truetype_font_write_hhea_table (cairo_truetype_font_t *font, unsigned long
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 @@ cairo_truetype_font_write_hmtx_table (cairo_truetype_font_t *font,
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 @@ cairo_truetype_font_write_hmtx_table (cairo_truetype_font_t *font,
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 @@ cairo_truetype_font_write_loca_table (cairo_truetype_font_t *font,
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 @@ cairo_truetype_font_write_maxp_table (cairo_truetype_font_t *font,
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 @@ cairo_truetype_font_use_glyph (cairo_truetype_font_t *font,
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 @@ cairo_truetype_subset_init_internal (cairo_truetype_subset_t *truetype_subse
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 @@ cairo_truetype_subset_init_internal (cairo_truetype_subset_t *truetype_subse
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 @@ cairo_truetype_subset_init_internal (cairo_truetype_subset_t *truetype_subse
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 @@ _cairo_truetype_reverse_cmap (cairo_scaled_font_t *scaled_font,
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 @@ find_name (tt_name_t *name, int name_id, int platform, int encoding, int languag
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 @@ find_name (tt_name_t *name, int name_id, int platform, int encoding, int languag
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 @@ find_name (tt_name_t *name, int name_id, int platform, int encoding, int languag
}
}
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 @@ _cairo_truetype_read_font_name (cairo_scaled_font_t *scaled_font,
if (status)
return status;
- name = malloc (size);
+ name = _cairo_malloc (size);
if (name == NULL)
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
diff --git a/Build/source/libs/cairo/cairo-src/src/cairo-type1-fallback.c b/Build/source/libs/cairo/cairo-src/src/cairo-type1-fallback.c
index c8e7e908bb6..0b8e66cd0b9 100644
--- a/Build/source/libs/cairo/cairo-src/src/cairo-type1-fallback.c
+++ b/Build/source/libs/cairo/cairo-src/src/cairo-type1-fallback.c
@@ -760,7 +760,7 @@ _cairo_type1_fallback_init_internal (cairo_type1_subset_t *type1_subset,
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;
diff --git a/Build/source/libs/cairo/cairo-src/src/cairo-type1-subset.c b/Build/source/libs/cairo/cairo-src/src/cairo-type1-subset.c
index feac2836f00..5f07456888b 100644
--- a/Build/source/libs/cairo/cairo-src/src/cairo-type1-subset.c
+++ b/Build/source/libs/cairo/cairo-src/src/cairo-type1-subset.c
@@ -311,7 +311,7 @@ cairo_type1_font_subset_get_matrix (cairo_type1_font_subset_t *font,
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 @@ cairo_type1_font_subset_get_matrix (cairo_type1_font_subset_t *font,
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 @@ cairo_type1_font_subset_get_fontname (cairo_type1_font_subset_t *font)
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 @@ cairo_type1_font_subset_decrypt_eexec_segment (cairo_type1_font_subset_t *font)
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 @@ cairo_type1_font_subset_parse_charstring (cairo_type1_font_subset_t *font,
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 @@ cairo_type1_font_subset_build_glyph_list (cairo_type1_font_subset_t *font,
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 @@ cairo_type1_font_subset_write_private_dict (cairo_type1_font_subset_t *font,
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 @@ cairo_type1_font_subset_write_private_dict (cairo_type1_font_subset_t *font,
/* 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 @@ cairo_type1_font_subset_generate (void *abstract_font,
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,14 +1715,20 @@ _cairo_type1_subset_init (cairo_type1_subset_t *type1_subset,
{
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))
@@ -1762,7 +1768,7 @@ _cairo_type1_subset_init (cairo_type1_subset_t *type1_subset,
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;
diff --git a/Build/source/libs/cairo/cairo-src/src/cairo-type3-glyph-surface.c b/Build/source/libs/cairo/cairo-src/src/cairo-type3-glyph-surface.c
index c99d461066c..6b21023190c 100644
--- a/Build/source/libs/cairo/cairo-src/src/cairo-type3-glyph-surface.c
+++ b/Build/source/libs/cairo/cairo-src/src/cairo-type3-glyph-surface.c
@@ -78,19 +78,19 @@ _cairo_type3_glyph_surface_create (cairo_scaled_font_t *scaled_font,
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));
_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 @@ _cairo_type3_glyph_surface_create (cairo_scaled_font_t *scaled_font,
* 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_show_glyphs (void *abstract_surface,
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 @@ _cairo_type3_glyph_surface_emit_fallback_image (cairo_type3_glyph_surface_t *sur
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 @@ _cairo_type3_glyph_surface_emit_glyph (void *abstract_surface,
"%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;
diff --git a/Build/source/libs/cairo/cairo-src/src/cairo-types-private.h b/Build/source/libs/cairo/cairo-src/src/cairo-types-private.h
index 3d15d968e4b..da373030c26 100644
--- a/Build/source/libs/cairo/cairo-src/src/cairo-types-private.h
+++ b/Build/source/libs/cairo/cairo-src/src/cairo-types-private.h
@@ -194,6 +194,7 @@ struct _cairo_font_options {
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 {
diff --git a/Build/source/libs/cairo/cairo-src/src/cairo-unicode.c b/Build/source/libs/cairo/cairo-src/src/cairo-unicode.c
index 88de39516b6..966ae84b59b 100644
--- a/Build/source/libs/cairo/cairo-src/src/cairo-unicode.c
+++ b/Build/source/libs/cairo/cairo-src/src/cairo-unicode.c
@@ -342,6 +342,36 @@ _cairo_ucs4_to_utf8 (uint32_t unicode,
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 @@ _cairo_utf8_to_utf16 (const char *str,
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);
}
diff --git a/Build/source/libs/cairo/cairo-src/src/cairo-user-font.c b/Build/source/libs/cairo/cairo-src/src/cairo-user-font.c
index 6d2de2097d5..a26fb57ee10 100644
--- a/Build/source/libs/cairo/cairo-src/src/cairo-user-font.c
+++ b/Build/source/libs/cairo/cairo-src/src/cairo-user-font.c
@@ -402,7 +402,7 @@ _cairo_user_font_face_scaled_font_create (void *abstract_
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_create (void)
{
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;
diff --git a/Build/source/libs/cairo/cairo-src/src/cairo-version.c b/Build/source/libs/cairo/cairo-src/src/cairo-version.c
index a94cef6819d..65ae2b108e2 100644
--- a/Build/source/libs/cairo/cairo-src/src/cairo-version.c
+++ b/Build/source/libs/cairo/cairo-src/src/cairo-version.c
@@ -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
* &nbsp;
* Run-time
* --------
diff --git a/Build/source/libs/cairo/cairo-src/src/cairo-vg-surface.c b/Build/source/libs/cairo/cairo-src/src/cairo-vg-surface.c
index 6e0d9a0ed69..77986331aa3 100644
--- a/Build/source/libs/cairo/cairo-src/src/cairo-vg-surface.c
+++ b/Build/source/libs/cairo/cairo-src/src/cairo-vg-surface.c
@@ -1517,7 +1517,7 @@ _vg_surface_create_internal (cairo_vg_context_t *context,
{
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 @@ _vg_surface_create_internal (cairo_vg_context_t *context,
_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_create_for_glx (Display *dpy, GLXContext ctx)
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_create_for_egl (EGLDisplay egl_display,
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;
diff --git a/Build/source/libs/cairo/cairo-src/src/cairo-vg.h b/Build/source/libs/cairo/cairo-src/src/cairo-vg.h
index f9a62e51c69..a2701db3bd4 100644
--- a/Build/source/libs/cairo/cairo-src/src/cairo-vg.h
+++ b/Build/source/libs/cairo/cairo-src/src/cairo-vg.h
@@ -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 © 2007 * Mozilla Corporation
- * Copyright © 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
diff --git a/Build/source/libs/cairo/cairo-src/src/cairo-win32.h b/Build/source/libs/cairo/cairo-src/src/cairo-win32.h
index 3d2e1c60169..db4cac69f49 100644
--- a/Build/source/libs/cairo/cairo-src/src/cairo-win32.h
+++ b/Build/source/libs/cairo/cairo-src/src/cairo-win32.h
@@ -49,6 +49,10 @@ cairo_public cairo_surface_t *
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 *
diff --git a/Build/source/libs/cairo/cairo-src/src/cairo-xcb-connection.c b/Build/source/libs/cairo/cairo-src/src/cairo-xcb-connection.c
index 67897fa4ecc..51f5ee323cd 100644
--- a/Build/source/libs/cairo/cairo-src/src/cairo-xcb-connection.c
+++ b/Build/source/libs/cairo/cairo-src/src/cairo-xcb-connection.c
@@ -111,7 +111,7 @@ _cairo_xcb_connection_find_visual_formats (cairo_xcb_connection_t *connection,
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 @@ _cairo_xcb_connection_parse_xrender_formats (cairo_xcb_connection_t *connection,
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 @@ _cairo_xcb_connection_get (xcb_connection_t *xcb_connection)
}
}
- connection = malloc (sizeof (cairo_xcb_connection_t));
+ connection = _cairo_malloc (sizeof (cairo_xcb_connection_t));
if (unlikely (connection == NULL))
goto unlock;
diff --git a/Build/source/libs/cairo/cairo-src/src/cairo-xcb-screen.c b/Build/source/libs/cairo/cairo-src/src/cairo-xcb-screen.c
index d0019f9cdff..0d23ad3c3d9 100644
--- a/Build/source/libs/cairo/cairo-src/src/cairo-xcb-screen.c
+++ b/Build/source/libs/cairo/cairo-src/src/cairo-xcb-screen.c
@@ -249,7 +249,7 @@ _cairo_xcb_screen_get (xcb_connection_t *xcb_connection,
}
}
- screen = malloc (sizeof (cairo_xcb_screen_t));
+ screen = _cairo_malloc (sizeof (cairo_xcb_screen_t));
if (unlikely (screen == NULL))
goto unlock;
diff --git a/Build/source/libs/cairo/cairo-src/src/cairo-xcb-shm.c b/Build/source/libs/cairo/cairo-src/src/cairo-xcb-shm.c
index 2be2dac5bf9..763778ab2c4 100644
--- a/Build/source/libs/cairo/cairo-src/src/cairo-xcb-shm.c
+++ b/Build/source/libs/cairo/cairo-src/src/cairo-xcb-shm.c
@@ -209,7 +209,7 @@ _cairo_xcb_connection_allocate_shm_info (cairo_xcb_connection_t *connection,
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);
diff --git a/Build/source/libs/cairo/cairo-src/src/cairo-xcb-surface-core.c b/Build/source/libs/cairo/cairo-src/src/cairo-xcb-surface-core.c
index 9c0c0a0957d..91c0ff995e4 100644
--- a/Build/source/libs/cairo/cairo-src/src/cairo-xcb-surface-core.c
+++ b/Build/source/libs/cairo/cairo-src/src/cairo-xcb-surface-core.c
@@ -85,7 +85,7 @@ _cairo_xcb_pixmap_create (cairo_xcb_surface_t *target,
{
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_xcb_pixmap_create (cairo_xcb_surface_t *target,
_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_copy (cairo_xcb_surface_t *target)
{
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_xcb_pixmap_copy (cairo_xcb_surface_t *target)
_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;
diff --git a/Build/source/libs/cairo/cairo-src/src/cairo-xcb-surface-render.c b/Build/source/libs/cairo/cairo-src/src/cairo-xcb-surface-render.c
index 139dcda827a..42f27c71fe2 100644
--- a/Build/source/libs/cairo/cairo-src/src/cairo-xcb-surface-render.c
+++ b/Build/source/libs/cairo/cairo-src/src/cairo-xcb-surface-render.c
@@ -114,7 +114,7 @@ _cairo_xcb_picture_create (cairo_xcb_screen_t *screen,
{
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_xcb_picture_create (cairo_xcb_screen_t *screen,
_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_create (cairo_xcb_connection_t *connection,
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 @@ _cairo_xcb_glyph_fini (cairo_scaled_glyph_private_t *glyph_private,
}
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_attach (cairo_xcb_connection_t *c,
{
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 @@ _cairo_xcb_surface_add_glyph (cairo_xcb_connection_t *connection,
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 @@ _cairo_xcb_surface_add_glyph (cairo_xcb_connection_t *connection,
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 @@ _emit_glyphs_chunk (cairo_xcb_surface_t *dst,
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);
}
diff --git a/Build/source/libs/cairo/cairo-src/src/cairo-xcb-surface.c b/Build/source/libs/cairo/cairo-src/src/cairo-xcb-surface.c
index df49e8269b9..7f601bb71c1 100644
--- a/Build/source/libs/cairo/cairo-src/src/cairo-xcb-surface.c
+++ b/Build/source/libs/cairo/cairo-src/src/cairo-xcb-surface.c
@@ -1075,14 +1075,15 @@ _cairo_xcb_surface_create_internal (cairo_xcb_screen_t *screen,
{
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));
_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;
diff --git a/Build/source/libs/cairo/cairo-src/src/cairo-xlib-core-compositor.c b/Build/source/libs/cairo/cairo-src/src/cairo-xlib-core-compositor.c
index 5babcc81bed..1392999617f 100644
--- a/Build/source/libs/cairo/cairo-src/src/cairo-xlib-core-compositor.c
+++ b/Build/source/libs/cairo/cairo-src/src/cairo-xlib-core-compositor.c
@@ -632,9 +632,10 @@ _cairo_xlib_core_compositor_fill (const cairo_compositor_t *compositor,
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 @@ _cairo_xlib_core_compositor_get (void)
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;
diff --git a/Build/source/libs/cairo/cairo-src/src/cairo-xlib-display.c b/Build/source/libs/cairo/cairo-src/src/cairo-xlib-display.c
index a2a3bc7924b..add42299b4c 100644
--- a/Build/source/libs/cairo/cairo-src/src/cairo-xlib-display.c
+++ b/Build/source/libs/cairo/cairo-src/src/cairo-xlib-display.c
@@ -207,7 +207,7 @@ _cairo_xlib_device_create (Display *dpy)
}
}
- 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;
diff --git a/Build/source/libs/cairo/cairo-src/src/cairo-xlib-private.h b/Build/source/libs/cairo/cairo-src/src/cairo-xlib-private.h
index 0f2f2e1faa0..71dccc3a725 100644
--- a/Build/source/libs/cairo/cairo-src/src/cairo-xlib-private.h
+++ b/Build/source/libs/cairo/cairo-src/src/cairo-xlib-private.h
@@ -104,7 +104,7 @@ struct _cairo_xlib_display {
* 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.
diff --git a/Build/source/libs/cairo/cairo-src/src/cairo-xlib-render-compositor.c b/Build/source/libs/cairo/cairo-src/src/cairo-xlib-render-compositor.c
index 8a1ec7bd731..0db59a8a6f5 100644
--- a/Build/source/libs/cairo/cairo-src/src/cairo-xlib-render-compositor.c
+++ b/Build/source/libs/cairo/cairo-src/src/cairo-xlib-render-compositor.c
@@ -965,7 +965,7 @@ _cairo_xlib_font_fini (cairo_scaled_font_private_t *abstract_private,
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_xlib_font_fini (cairo_scaled_font_private_t *abstract_private,
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_create (cairo_xlib_display_t *display,
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_attach (cairo_xlib_display_t *display,
{
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 @@ _cairo_xlib_surface_add_glyph (cairo_xlib_display_t *display,
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 @@ _cairo_xlib_surface_add_glyph (cairo_xlib_display_t *display,
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 @@ composite_glyphs (void *surface,
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 @@ _cairo_xlib_mask_compositor_get (void)
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 @@ composite_traps (void *abstract_dst,
//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 @@ composite_tristrip (void *abstract_dst,
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 @@ _cairo_xlib_traps_compositor_get (void)
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;
diff --git a/Build/source/libs/cairo/cairo-src/src/cairo-xlib-screen.c b/Build/source/libs/cairo/cairo-src/src/cairo-xlib-screen.c
index 57beeaab426..ff3bdfcf9e1 100644
--- a/Build/source/libs/cairo/cairo-src/src/cairo-xlib-screen.c
+++ b/Build/source/libs/cairo/cairo-src/src/cairo-xlib-screen.c
@@ -330,7 +330,7 @@ _cairo_xlib_screen_get (Display *dpy,
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;
diff --git a/Build/source/libs/cairo/cairo-src/src/cairo-xlib-source.c b/Build/source/libs/cairo/cairo-src/src/cairo-xlib-source.c
index 1591f5874f6..6269edca53e 100644
--- a/Build/source/libs/cairo/cairo-src/src/cairo-xlib-source.c
+++ b/Build/source/libs/cairo/cairo-src/src/cairo-xlib-source.c
@@ -109,7 +109,7 @@ source (cairo_xlib_surface_t *dst, Picture picture, Pixmap pixmap)
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 @@ source (cairo_xlib_surface_t *dst, Picture picture, Pixmap pixmap)
_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 @@ static cairo_xlib_source_t *init_source (cairo_xlib_surface_t *dst,
_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,14 +966,15 @@ surface_source (cairo_xlib_surface_t *dst,
_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);
_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,
diff --git a/Build/source/libs/cairo/cairo-src/src/cairo-xlib-surface-shm.c b/Build/source/libs/cairo/cairo-src/src/cairo-xlib-surface-shm.c
index 9824eff823b..1ee1e3d70f4 100644
--- a/Build/source/libs/cairo/cairo-src/src/cairo-xlib-surface-shm.c
+++ b/Build/source/libs/cairo/cairo-src/src/cairo-xlib-surface-shm.c
@@ -573,7 +573,7 @@ _cairo_xlib_shm_pool_create(cairo_xlib_display_t *display,
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 @@ _cairo_xlib_shm_info_create (cairo_xlib_display_t *display,
assert (mem != NULL);
- info = malloc (sizeof (*info));
+ info = _cairo_malloc (sizeof (*info));
if (info == NULL) {
_cairo_mempool_free (&pool->mem, mem);
return NULL;
@@ -814,14 +814,15 @@ _cairo_xlib_shm_surface_create (cairo_xlib_surface_t *other,
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);
_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 @@ _cairo_xlib_display_init_shm (cairo_xlib_display_t *display)
if (!can_use_shm (display->display, &has_pixmap))
return;
- shm = malloc (sizeof (*shm));
+ shm = _cairo_malloc (sizeof (*shm));
if (unlikely (shm == NULL))
return;
diff --git a/Build/source/libs/cairo/cairo-src/src/cairo-xlib-surface.c b/Build/source/libs/cairo/cairo-src/src/cairo-xlib-surface.c
index ee14af2786d..2a6d896d3b9 100644
--- a/Build/source/libs/cairo/cairo-src/src/cairo-xlib-surface.c
+++ b/Build/source/libs/cairo/cairo-src/src/cairo-xlib-surface.c
@@ -189,12 +189,6 @@ _cairo_surface_is_xlib (cairo_surface_t *surface);
#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 @@ found:
;
}
- 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 @@ found:
_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 @@ static cairo_bool_t valid_size (int width, int height)
/* 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 &&
diff --git a/Build/source/libs/cairo/cairo-src/src/cairo-xlib-visual.c b/Build/source/libs/cairo/cairo-src/src/cairo-xlib-visual.c
index 863822eebbd..979cd5b36b4 100644
--- a/Build/source/libs/cairo/cairo-src/src/cairo-xlib-visual.c
+++ b/Build/source/libs/cairo/cairo-src/src/cairo-xlib-visual.c
@@ -82,7 +82,7 @@ _cairo_xlib_visual_info_create (Display *dpy,
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);
diff --git a/Build/source/libs/cairo/cairo-src/src/cairo-xlib-xcb-surface.c b/Build/source/libs/cairo/cairo-src/src/cairo-xlib-xcb-surface.c
index af3e1557899..4fa9f288328 100644
--- a/Build/source/libs/cairo/cairo-src/src/cairo-xlib-xcb-surface.c
+++ b/Build/source/libs/cairo/cairo-src/src/cairo-xlib-xcb-surface.c
@@ -391,7 +391,7 @@ _cairo_xlib_xcb_device_create (Display *dpy, cairo_device_t *xcb_device)
}
}
- 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 @@ _cairo_xlib_xcb_surface_create (void *dpy,
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_xlib_xcb_surface_create (void *dpy,
_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);
diff --git a/Build/source/libs/cairo/cairo-src/src/cairo-xml-surface.c b/Build/source/libs/cairo/cairo-src/src/cairo-xml-surface.c
index 6dbafdba2ba..35773a2b225 100644
--- a/Build/source/libs/cairo/cairo-src/src/cairo-xml-surface.c
+++ b/Build/source/libs/cairo/cairo-src/src/cairo-xml-surface.c
@@ -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_create_internal (cairo_output_stream_t *stream)
{
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 @@ _cairo_xml_emit_type42_font (cairo_xml_t *xml,
if (unlikely (status))
return status;
- buf = malloc (size);
+ buf = _cairo_malloc (size);
if (unlikely (buf == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
@@ -1098,14 +1098,15 @@ _cairo_xml_surface_create_internal (cairo_device_t *device,
{
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));
_cairo_surface_init (&surface->base,
&_cairo_xml_surface_backend,
device,
- content);
+ content,
+ TRUE); /* is_vector */
surface->width = width;
surface->height = height;
diff --git a/Build/source/libs/cairo/cairo-src/src/cairo.c b/Build/source/libs/cairo/cairo-src/src/cairo.c
index e3acf4d46c7..ca0c91e8b04 100644
--- a/Build/source/libs/cairo/cairo-src/src/cairo.c
+++ b/Build/source/libs/cairo/cairo-src/src/cairo.c
@@ -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>
+ * /&ast; Create a hyperlink &ast;/
+ * 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);
+ *
+ * /&ast; Create a destination &ast;/
+ * 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 @@ static const cairo_t _cairo_nil[] = {
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 @@ _cairo_init (cairo_t *cr,
* @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 @@ slim_hidden_def (cairo_set_operator);
#if 0
-/**
+/*
* cairo_set_opacity:
* @cr: a #cairo_t
* @opacity: the level of opacity to use when compositing
@@ -635,9 +854,7 @@ slim_hidden_def (cairo_set_operator);
* 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_copy_clip_rectangle_list (cairo_t *cr)
}
/**
+ * 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
diff --git a/Build/source/libs/cairo/cairo-src/src/cairo.h b/Build/source/libs/cairo/cairo-src/src/cairo.h
index 3104d47e4c4..3492bdc6bf9 100644
--- a/Build/source/libs/cairo/cairo-src/src/cairo.h
+++ b/Build/source/libs/cairo/cairo-src/src/cairo.h
@@ -292,6 +292,10 @@ typedef struct _cairo_user_data_key {
* @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 @@ typedef enum _cairo_status {
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 @@ typedef enum _cairo_content {
* @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 @@ cairo_pop_group_to_source (cairo_t *cr);
* 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_copy_clip_rectangle_list (cairo_t *cr);
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 @@ typedef struct _cairo_scaled_font cairo_scaled_font_t;
*
* 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_font_options_set_hint_metrics (cairo_font_options_t *options,
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_status (cairo_surface_t *surface);
* @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 @@ cairo_surface_set_user_data (cairo_surface_t *surface,
#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,
diff --git a/Build/source/libs/cairo/cairo-src/src/cairoint.h b/Build/source/libs/cairo/cairo-src/src/cairoint.h
index 555aa899030..cfae18cf93b 100644
--- a/Build/source/libs/cairo/cairo-src/src/cairoint.h
+++ b/Build/source/libs/cairo/cairo-src/src/cairoint.h
@@ -107,6 +107,12 @@ _cairo_win32_tmpfile (void);
#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 @@ _cairo_isdigit (int c)
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 @@ typedef enum _cairo_scaled_glyph_info {
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 @@ struct _cairo_scaled_font_backend {
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 @@ struct _cairo_scaled_font_backend {
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 @@ _cairo_font_options_init_copy (cairo_font_options_t *options,
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 @@ _cairo_validate_text_clusters (const char *utf8,
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,7 +925,10 @@ cairo_private void
_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 *
@@ -1021,6 +1050,7 @@ cairo_private void
_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_glyph_set_recording_surface (cairo_scaled_glyph_t *scaled_glyph,
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_stroke_style_dash_approximate (const cairo_stroke_style_t *style,
/* 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_private void
_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 @@ _cairo_surface_show_text_glyphs (cairo_surface_t *surface,
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 @@ _cairo_surface_release_device_reference (cairo_surface_t *surface);
* 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_image_scaled_glyph_fini (cairo_scaled_font_t *scaled_font,
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 @@ _cairo_matrix_to_pixman_matrix_offset (const cairo_matrix_t *matrix,
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_private int
_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_matrix_multiply (cairo_matrix_t *r,
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 @@ _cairo_debug_check_image_surface_is_defined (const cairo_surface_t *surface);
#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);
diff --git a/Build/source/libs/cairo/cairo-src/src/test-compositor-surface.c b/Build/source/libs/cairo/cairo-src/src/test-compositor-surface.c
index 1cc5f692120..d6e04a122c2 100644
--- a/Build/source/libs/cairo/cairo-src/src/test-compositor-surface.c
+++ b/Build/source/libs/cairo/cairo-src/src/test-compositor-surface.c
@@ -78,7 +78,7 @@ test_compositor_surface_create (const cairo_compositor_t *compositor,
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 @@ test_compositor_surface_create (const cairo_compositor_t *compositor,
_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;
diff --git a/Build/source/libs/cairo/cairo-src/src/test-null-compositor-surface.c b/Build/source/libs/cairo/cairo-src/src/test-null-compositor-surface.c
index 2301055e30a..35913a2b9fb 100644
--- a/Build/source/libs/cairo/cairo-src/src/test-null-compositor-surface.c
+++ b/Build/source/libs/cairo/cairo-src/src/test-null-compositor-surface.c
@@ -81,7 +81,7 @@ test_compositor_surface_create (const cairo_compositor_t *compositor,
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 @@ test_compositor_surface_create (const cairo_compositor_t *compositor,
_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 @@ check_composite (const cairo_composite_rectangles_t *extents)
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 @@ no_traps_compositor_get (void)
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 @@ no_traps_compositor_get (void)
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 @@ no_spans_compositor_get (void)
//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;
diff --git a/Build/source/libs/cairo/cairo-src/src/test-paginated-surface.c b/Build/source/libs/cairo/cairo-src/src/test-paginated-surface.c
index 0a7c79b37bf..7967f7406cd 100644
--- a/Build/source/libs/cairo/cairo-src/src/test-paginated-surface.c
+++ b/Build/source/libs/cairo/cairo-src/src/test-paginated-surface.c
@@ -74,14 +74,15 @@ _cairo_test_paginated_surface_create (cairo_surface_t *target)
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));
_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,13 +232,15 @@ _test_paginated_surface_show_text_glyphs (void *abstract_surface,
}
-static void
+static cairo_int_status_t
_test_paginated_surface_set_paginated_mode (void *abstract_surface,
cairo_paginated_mode_t mode)
{
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 = {
diff --git a/Build/source/libs/cairo/configure b/Build/source/libs/cairo/configure
index 88aa5606f5c..905af910bf5 100755
--- a/Build/source/libs/cairo/configure
+++ b/Build/source/libs/cairo/configure
@@ -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@tug.org>.
#
@@ -580,8 +580,8 @@ MAKEFLAGS=
# 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@tug.org'
PACKAGE_URL=''
@@ -1349,7 +1349,7 @@ if test "$ac_init_help" = "long"; then
# 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 @@ fi
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 @@ fi
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 @@ cat >config.log <<_ACEOF
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 @@ fi
# 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 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
# 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 @@ _ACEOF
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\\"
diff --git a/Build/source/libs/cairo/version.ac b/Build/source/libs/cairo/version.ac
index 07c577c5867..6874654198b 100644
--- a/Build/source/libs/cairo/version.ac
+++ b/Build/source/libs/cairo/version.ac
@@ -8,4 +8,4 @@ dnl
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])